有没有一种方法可以强制一个程序只使用1个线程?

3

我正在linux上针对一段恼人的cpp程序进行基准测试。这个程序非常混乱和复杂!它自动执行多线程,我想知道是否有任何方法通过调用某些东西(例如taskset等)来强制它仅使用一个线程。

编辑:我已经尝试设置“taskset 01 program arg1 ...”,但它不起作用。我刚刚看到程序使用了100个线程!


@Brett - 怎么办?我不是管理员,而且还有其他人在使用这台服务器。 - user3639557
为什么你要问这个问题?如果你正在进行基准测试,那么你应该在预期的条件下运行程序,显然对于这个程序来说意味着多线程。也许大多数线程是空闲的,程序只能在一个或两个核心上运行。因此,请编辑你的问题以更好地说明动机。 - Basile Starynkevitch
顺便提一下,你漏了一个“Linux”标签。另外,为什么只在一两个核心上对你的程序进行基准测试会让你不开心呢? - Basile Starynkevitch
但是,限制核心(不是线程!)的数量就足够了。也许线程的数量可以进行配置(至少通过重新编译源代码)。 - Basile Starynkevitch
不是真的。这段代码对I/O非常敏感,因此多线程实际上会产生无意义的时间结果。 - user3639557
4个回答

3

(我认为您接受针对Linux的解决方案)

在Linux上,使用clone(2)系统调用来创建线程(至少是NPTL线程)。它有可能会失败,错误信息如下:

EAGAIN 进程数已达到系统上限; 请参考fork(2)。

(实际上,内核正在调度任务,这些任务可能是线程或[单线程]进程)

您可以使用setrlimit(2)中的RLIMIT_NPROC选项:

RLIMIT_NPROC 在调用进程的真实用户ID下可创建的进程数(或更精确地说,在Linux下是可创建的线程数)。

因此,我猜您可以使用它来限制成功创建的线程(实际上是“任务”)数量。也许您可以将其与终端中运行的shell的ulimit内置命令一起使用。

但是我不确定这是否是一个好主意。一个良好编写的程序会针对pthread_create(3)(内部调用clone(2))的错误进行测试。而糟糕编写的程序则可能会崩溃。

也许该程序正在使用一些线程池,并且存在一种限制该池大小的方法。顺便说一下,您可以在仅有两个核心 - 或甚至一个单独的核心 - 上运行数十个线程(尤其是当大多数时间这些线程处于空闲状态时,例如poll(2)等待I/O)。

PS. 为了进行基准测试,您可能更应该关心通过taskset限制核心数量,而不是限制线程数量。


限制线程的程序是 prlimit --nproc=1 prog [args]。我尝试使用它与 rsync,但出现了“fork unavailable... error in IPC”的错误提示,最终结果是 rsync 不支持单线程工作。 - Martian2020

3
为了将Linux进程限制为仅在一个核心上运行,请使用taskset。以下内容摘自https://serverfault.com/a/32331
taskset <affinity mask> -p <process>

taskset 1 -p 12345

将进程12345设置为仅使用处理器/核心1

位掩码可以是列表(即1、3、4,以使用4+核心系统的核心1、3和4)或十六进制位掩码(0x0000000D表示1、3、4,0x00000001表示仅核心1)

taskset通常包含在名为shedutils的软件包中。

编辑:几乎忘了...如果您想为新命令设置亲和性而不是更改现有进程的亲和性,请使用:

taskset <mask> <program> [<arg1>]...[<argN>]

你的解决方案只适用于Linux,你应该在某个地方写下来。 - user3053231
我尝试过设置“taskset 01 program arg1 ...”,但它没有起作用。我刚刚看到该程序使用了41个线程! - user3639557
@user3639557 在你提出的问题中写道“...或至少1个核心”,这是对此的回答。 - anatolyg
@anatolyg修正了这个问题。 - user3639557
是的,taskset 控制一个进程能够运行的核心数量。它不控制线程的数量。程序中的代码必须提供限制线程数量的功能。例如,如果我编写了一个生成线程的程序,就没有外部方法来停止它;taskset 可以让程序的所有线程都在一组核心上运行。但它不能阻止程序运行线程。 - Phil

1
如果程序尝试生成线程,除非程序本身有一些命令行选项来限制线程,否则您无法阻止它。

1
但是你可以限制这些线程只在特定的核心上运行,而且你可以限制它可以运行的核心数量 - Jesper Juhl

0
如果你想要执行单个文件而非指定的进程,以下 taskset 命令格式可能会有所帮助:
taskset 1 file 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接