有没有办法强制程序只使用 1 个线程?

Posted

技术标签:

【中文标题】有没有办法强制程序只使用 1 个线程?【英文标题】:Is there a way force a program to use only 1 thread? 【发布时间】:2016-07-28 13:12:24 【问题描述】:

我正在对 linux 上一个烦人的 cpp 程序进行基准测试。该程序是一团糟,复杂得要命!它会自动执行多线程,我想知道是否有任何方法可以通过某种方式(即任务集等)强制调用它以仅使用 1 个线程。

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

【问题讨论】:

@Brett - 怎么样?我不是管理员,还有其他人在使用服务器。 你为什么要问?如果您进行基准测试,您应该在预期的条件下运行程序,显然对于该程序来说这意味着多线程。也许大多数线程都是空闲的,程序只能在一个或两个内核上运行。所以编辑你的问题来激发它。 顺便说一句,您缺少Linux 标签。另外,为什么只在一个或两个内核上对您的程序进行基准测试会让您不满意? 但是,限制核心(不是线程!)的数量就足够了。也许线程数是可配置的(至少通过重新编译源代码)。 并非如此。代码对 I/O 非常敏感,因此多线程实际上在时序方面会产生无意义的结果。 【参考方案1】:

要限制 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,你应该把它写在某个地方。 已尝试设置“taskset 01 program arg1 ...”,但它不起作用。我刚刚看到程序使用了 41 个线程! @user3639557 您在问题中写了“...或至少 1 个核心”,所以这是对它的回答。 @anatolyg 解决了这个问题。 是的,taskset 控制进程能够运行的内核数量。它不控制线程数。程序中的代码必须提供限制线程数量的能力。例如,如果我编写了一个产生线程的程序,则没有外部方法可以阻止它; taskset 为您提供了一种让程序的所有线程在一组内核上运行的方法。它不会也不能阻止程序运行线程。【参考方案2】:

(我假设您接受 Linux 特定的解决方案)

在 Linux 上,线程(至少 NPTL 线程)是使用 clone(2) 系统调用创建的。它被记录为失败

EAGAIN太多进程已经在运行;参见 fork(2)。

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

您可以将setrlimit(2) 与RLIMIT_NPROC 一起使用:

RLIMIT_NPROC 最大进程数(或者,更准确地说,在 Linux 上, threads),可以为真正的用户 ID 创建 调用过程。

所以我猜你可能会使用它(也许在终端中运行的 shell 中使用 ulimit bash 内置)来限制成功创建线程的数量(实际上是“任务”)。

但我不确定这是否是个好主意。一个编写良好的程序将测试pthread_create(3)(内部调用clone(2))的失败。写得不好的程序会崩溃。

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

PS。出于基准测试的目的,您可能应该更关心限制内核数量(使用taskset)而不是限制线程数量。

【讨论】:

限制线程的程序是prlimit --nproc=1 prog [args]。我尝试将它与rsync 一起使用并得到“fork 不可用... IPC 中的错误”,最后 - rsync 被写入不能作为一个线程工作。【参考方案3】:

如果程序试图产生线程,你无法阻止它 - 除非程序本身有一些命令行选项会限制线程。

【讨论】:

但是您可以限制这些线程只在某些核心上运行,并且您可以限制它的核心数量可以继续运行。

以上是关于有没有办法强制程序只使用 1 个线程?的主要内容,如果未能解决你的问题,请参考以下文章

多核 C++ 线程

强制终止由 Parallel.ForEach 生成的线程 [重复]

有没有办法强行杀死python中的线程?

Python强制关闭线程的一种办法(可行已用于项目)

强制 Alamofire 在主线程上做所有事情?

在所有异步套接字回调上强制线程 CultureInfo