代码之家  ›  专栏  ›  技术社区  ›  Alexis Wilke

pthread_create()之后线程的漂亮值是多少?

  •  0
  • Alexis Wilke  · 技术社区  · 3 年前

    我正在使用libx264库将视频数据压缩为…x264。

    我使用默认值让库创建它想要的任意多(几个)线程:

    param.i_threads = X264_THREADS_AUTO;
    

    这在我的服务器上运行得很好,我的服务器有64个处理器(2个CPU,每个CPU有16个核心和英特尔线程)。它实际上将使用大约5个线程。

    然而,在运行该软件的嵌入式计算机上,我只有4个CPU。它是一个Xeon,所以没有太多问题,但不知何故,它阻止了USB端口的工作。我们从USB端口接收数据,当4个CPU以大约100%的速度使用时,libx264代码会非常糟糕地接管整个计算机。

    我想到了两种解决方案,使用3作为线程的最大数量:

    param.i_threads = 3;
    

    或者让那些libx264线程具有(高得多)的漂亮值,这样在该计算机上运行的其他东西就不会被阻塞(即CPU更好地共享;其他东西不使用太多CPU,通常远低于10%)。

    然而,我无法控制libx264库是如何创建线程的,我想知道在调用创建线程的libx264函数之前更改nice值是否有效,从而使这些线程使用该nice值,如下所示:

    nice(10);
    ...call libx264 functions...
    nice(0);
    

    使这些线程使用+10的值的意愿?从我所看到的 pthread_create() man page,它没有明确地说线程继承了父线程的nice值。。。


    注1: 我知道这个问题并非不可能,因为USB端口可能正在与视频捕获卡争夺DMA。。。如果是这样的话,我们显然不会仅仅通过更改流程的优先级来解决任何问题。我想先试试那个软性的解决方案。

    虽然我可以将USB端口移动到另一台计算机,但数据将通过网络传输,这很可能会出现类似的硬件冲突问题。


    注2: 我不想重新编译libx264并更改代码。这远远超出了我的项目范围。

    0 回复  |  直到 3 年前
        1
  •  0
  •   Alexis Wilke    3 年前

    首先,X264库在使用打开句柄时创建线程 x264_encoder_open() 。这是唯一需要更新漂亮值的函数。

    正如Peter Cordes在一条评论中指出的那样,只有当您以root身份运行时,以下操作才有效(通常不建议这样做,即使对于守护进程也是如此):

    nice(10);
    ...call libx264 functions...
    nice(0);
    

    这也是错误的,因为 nice(0) 只会返回当前的漂亮值。正确的调用是 nice(-10) .

    一种解决方案是授予进程成为root用户的权限,并且在尝试执行 不错(-10) ,在之前成为root,然后删除权限。

    // change nice(2) to non-preemptive
    int inc_nice = 10;
    nice(inc_nice);
    
    // create the X264 threads
    x264_encoder_open(&params);
    
    // restore the nice value
    uid_t user(getuid());
    seteuid(0);
    nice(-inc_nice);
    seteuid(user);
    

    请注意,如果您使用多个线程运行,则此代码为 不安全 。当时 seteuid(0) 返回时,您的其他线程将具有root权限。假设你的应用程序是安全的,这应该不是一个大问题,但仍然需要记住。

    要使systemd服务有权成为root用户,您需要以下内容:

    1. 这假设您正在使用“用户”和“组”选项在启动时放弃特权。如果您的守护进程以root身份运行,那么您甚至不需要特殊处理。你可以打电话给 不错(-10) 它会起作用的。

      Debian上的web服务器使用以下内容:

       User=www-data
       Group=www-data
      
    2. 赋予进程特权:

      要么设置 NoNewPrivileges 为false(或者不包括它,因为这是默认值):

       NoNewPrivileges=false
      
    3. 为流程提供成为root用户的选项:

      您需要确保进程所有者是root用户,并且's'标志(也称为。 在执行时设置用户 )已设置:

       chown root /usr/sbin/my-app
       chmod u+s /usr/sbin/my-app
      

      在大多数情况下,如果您使用Linux系统的标准打包程序,则安装在 /usr/sbin 将已由root拥有。但是,默认情况下不会设置的'标志。创建Debian包时,可以添加 debian/rules 文件中包含以下内容:

       override_dh_fixperms:
           dh_fixperms
           chmod u+s debian/project-name/usr/sbin/my-app
      

      注: rules file是一个makefile,所以缩进应该是一个选项卡。