简体   繁体   中英

Setting CPU affinity to a process - C - Linux

Not the best in C programming, here is my first trial to port a program from python to C. Credits to Alnitak for the program below

#include<sched.h>

void task_set(int pid) {
        int result;
        cpu_set_t  mask;
        CPU_ZERO(&mask);
        CPU_SET(pid, &mask);
        result = sched_setaffinity(0, sizeof(mask), &mask);
        printf ("%d\n",result);
}

void main()
{ //excuse me for the static
task_set(1400);
}

To compile I did this..

gcc -D_GNU_SOURCE -o test test.c

However, when I try to go back and check where the program is running using the following script:

def which_core(pid):
        f = file(os.path.join('/proc', str(fpid), 'stat'), 'rb')
        val = f.read()
        f.close()
        return int(val.split(' ')[-6])
print 'core_id',which_core(1400)

It gives me the following output:

core_id 32997376

It is quite confusing there... what is the mistake?

OK. This is the stupidest thing that one can ever do!

    CPU_SET(pid, &mask);

    CPU_SET(coreid, &mask);

changing the pid to the coreid will do it.

The other mistake was here:

    result = sched_setaffinity(pid, sizeof(mask), &mask);

You're probably looking for field 39 (counting from 1)

processor %d (since Linux 2.2.8) CPU number last executed on.

(from man proc )

(edit: looks like -6 = 39 after all, sorry for not noticing that :-P )

Parsing the /proc/[pid]/stat files is a bit tricky, because you can have embedded spaces and parentheses in the file name. These are not escaped in any way.

To see the very real effects, run

cp /bin/cat ') fake (' && './) fake (' < /proc/self/stat && rm -f ') fake ('

The correct procedure is to take everything up to but not including the first occurrence of " (" as pid , the process ID. Everything up to but not including the last occurrence of ") " is comm , the filename of the process executable. (None of the other fields are string-type, so you should not see any parentheses elsewhere in the file.) All the following fields are separated by spaces, and are listed in man 5 proc , under /proc/[pid]/stat . The processor is the 37th field following comm , or 39th field overall. (On Ubuntu 3.8.0-25-generic on x86-64, the field is 14th counting backwards from the end, not sixth -- but that is subject to change, as new fields can always be added to the end.)

If you limit yourself to Linux 2.6.26 and later (including all 3.xy versions and later), then you could just look at the Cpus_allowed_list: line in /proc/[pid]/status instead. It's easier to parse, and tells which cores the kernel will allow the process to run, not just which CPU the process last ran on (which the processor field in /proc/[pid]/stat describes).

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM