C语言 pthread_create()之后的线程的好值是什么?



我使用libx264库压缩视频数据到…x264 .

我使用默认值让库创建任意多(或少)的线程:

param.i_threads = X264_THREADS_AUTO;

这在我的服务器上工作得很好,它有64个处理器(2个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()手册页中看到的,它没有明确地说线程继承父线程的线程nice值…


注1:我知道这个问题不太可能是USB端口可能与视频采集卡争夺DMA的事实……如果是这样的话,我们显然不能仅仅通过改变进程的优先级来解决任何问题。我想先试试那种软性溶液。

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


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

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

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

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

也只不过是错误的因为nice(0)并返回当前好值。正确的调用nice(-10)

一种解决方案是赋予进程成为root的权限,当尝试执行nice(-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)返回时,您的其他线程将具有根权限。假设您的应用程序是安全的,这应该不是一个大问题,但仍然需要记住。

要使systemd服务拥有成为根用户的权利,你需要做以下事情:

  1. 这假设您正在使用User和Group选项在启动时放弃特权。如果您的守护进程以根用户身份运行,那么您甚至不需要特殊的处理。你可以调用nice(-10),它会工作的。

    以下是Debian web服务器使用的命令:

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

    NoNewPrivileges设置为false(或者不包含它,因为这是默认的):

    NoNewPrivileges=false
    
  3. 给进程一个成为根目录的选项:

    您需要确保进程所有者是根用户,并且设置了's'标志(也就是在执行时设置用户):

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

    在大多数情况下,如果您使用Linux系统的标准打包器,安装在/usr/sbin下的文件将已经由root拥有。但是,默认情况下不设置's'标志。在创建Debian软件包时,您可以添加一个debian/rules文件,如下所示:

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

    注意:rules文件是一个makefile,所以缩进应该是一个制表符

最新更新