97

How to limit process to one cpu core ?

Something similar to ulimit or cpulimit would be nice. (Just to ensure: I do NOT want to limit percentage usage or time of execution. I want to force app (with all it's children, processes (threads)) to use one cpu core (or 'n' cpu cores)).

Ciro Santilli OurBigBook.com
  • 18,092
  • 4
  • 117
  • 102
  • I've pointed out earlier that : Searching taskset on unix.SO gave me those two related questions : 1, 2 , where taskset is used. - It's similar question, that's why I linked this with them, but asked in different way, so I could not find it, when searching for my problem. Those questions where linked together when @DavidSchwartz shown taskset in his comment. – Grzegorz Wierzowiecki Oct 29 '11 at 10:13
  • Related: http://unix.stackexchange.com/q/247209/135943 – Wildcard Jan 21 '16 at 02:17
  • Very good question! – KansaiRobot Jul 09 '23 at 05:04

2 Answers2

109

Under Linux, execute the sched_setaffinity system call. The affinity of a process is the set of processors on which it can run. There's a standard shell wrapper: taskset. For example, to pin a process to CPU #0 (you need to choose a specific CPU):

taskset -c 0 mycommand --option  # start a command with the given affinity
taskset -c -pa 0 1234            # set the affinity of a running process

There are third-party modules for both Perl (Sys::CpuAffinity) and Python (affinity) to set a process's affinity. Both of these work on both Linux and Windows (Windows may require other third-party modules with Sys::CpuAffinity); Sys::CpuAffinity also works on several other unix variants.

If you want to set a process's affinity from the time of its birth, set the current process's affinity immediately before calling execve. Here's a trivial wrapper that forces a process to execute on CPU 0.

#!/usr/bin/env perl
use POSIX;
use Sys::CPUAffinity;
Sys::CpuAffinity::setAffinity(getpid(), [0]);
exec $ARGV[0] @ARGV
  • For a working solution for Python 3, see this answer to another question: https://stackoverflow.com/a/31370840/5079779 – Beefster May 19 '18 at 01:30
  • The problem is that the process can just call sched_setaffinity to undo the taskset and run on other CPUs: i.e., it isn't like a ulimit where the process is forced to stay within the limits. It's more like a suggestion. – BeeOnRope Jun 20 '19 at 23:52
  • @BeeOnRope Right, it isn't a security restriction. If you want a security restriction, you need different tools. I think you can do it with cgroups. – Gilles 'SO- stop being evil' Jun 21 '19 at 05:36
  • 1
    This doesn't work for me. I'm investigating: https://forum.peppermintos.com/index.php?topic=8777.new#new – Stefan Reich Aug 31 '19 at 01:57
  • 1
    When changing the CPU affinity of a running process, taskset -c -p 0 1234 will not work. We need to pass parameter -a as follows: taskset -c -p -a 0 1234. Check out the comments for this question – Nagabhushan S N Mar 10 '20 at 03:29
  • 3
    @NagabhushanSN It does work if the process is single-threaded. But for a multithreaded process you do need -a to affect all the threads, so it's a good idea to include it in my answer. I've done that, thanks. – Gilles 'SO- stop being evil' Mar 10 '20 at 08:40
  • 1
    Good answer works for me! – alan23273850 Feb 21 '23 at 04:43
  • Awesome! Adding the flag -a helped me set a multi-processor process to a limited set of CPU cores. FYI, I was trying to run it on the first four cores. so, I used -a 0-3 to specify that – asgs May 29 '23 at 09:59
7

You can build cpu-sets on the command line as well. man cpuset Later on you can assign (running) processes to these.

Nils
  • 18,492
  • I've checked out man page. Looks very interesting ! Thanks for this ! What about my question, I'd like to get processes assigned from their birth. Even thou, it's interesting to know how to assign running ones. :) – Grzegorz Wierzowiecki Oct 22 '11 at 22:10
  • It has been a long time that I actually needed that - it was on Solaris. Later on it was on HP-Unix. On Linux - hm. I think I once found an additional package in SLES that provides a shell-api for that stuff. A quick search on CentOS 5 turned out blank. I will come back to you, if I found something in that direction. BTW - wich Linux distribution are we talking about here? – Nils Oct 26 '11 at 19:23
  • I am looking for general solution. If some program is not delivered in standard distro, I can deliver it. What about my desktop: Arch64, Arch. On servers usually Gentoo. On ARM devices, usually small specific ones. – Grzegorz Wierzowiecki Oct 28 '11 at 07:38
  • 1
    My feeling is that you can do all the cpuset-magic with echo in /proc as well. But you are propably better off in your case with the python solution. - I see the command on the shell is taskset. – Nils Oct 28 '11 at 20:53
  • /proc is good tip, I have to check it out. Thanks. – Grzegorz Wierzowiecki Oct 29 '11 at 08:42