0
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    std::cout << "current cpu: " << sched_getcpu() << std::endl;
    CPU_SET(sched_getcpu(), &cpuset);
    if (pthread_setaffinity_np(std_thread.getNativeHandle(), sizeof(cpu_set_t), &cpuset) == 0) {
        std::cout << "Afinity ok!!!" << std::endl;
    } else {
        std::cout << "second thread set affinity failed." << std::endl;
    }

Basically i'm trying to have both the main thread(main()) and the new created thread(std_thread) to run in the same cpu. The code prints out "Afinity ok!!!" but when i check which cpu both threads are using in htop tool they randomly changes all the time which means the code failed.

  • 1
    Are you sure your first thread only has a single CPU set in its affinity mask? – Shawn Aug 15 '18 at 08:56
  • Thanks for the comment. Check the answer below, i fixed that but the result is still the same. @shawn –  Aug 15 '18 at 09:14

2 Answers2

2

If there is no hard reasons for doing this inside the code then you can use taskset command and can be done while process is created as well as during runtime

if you want to start the process in a particular CPU, give the number as

taskset -c <CPUNumber> ProgramName

or dynamically you can change using PID

taskset -cp <CPUNumber> PID
Daksh Gupta
  • 7,554
  • 2
  • 25
  • 36
  • I need two threads to run on the same core and the rest can be assigned by the OS. Or maybe in the future i may wish to setup each thread to its own core. –  Aug 15 '18 at 10:01
  • You can do the same by assigning same core number of thread ids as taskset -cp ThreadID – Daksh Gupta Aug 18 '18 at 12:24
1

With pthread_getaffinity_np(), you are getting the affinity of your thread in cpuset. If you check the value of this cpu set, you should notice that it spans all the cpus of your machine. Indeed, by default, threads can use any cpu of the machine. What your code is doing is just set the affinity of your other thread to the whole machine (in other words, nothing).

What you should do is actually set a single cpu in cpuset, and then set the affinity of both your threads. You can also use sched_getcpu() to get the cpu on which one of your thread is running, set this cpu in cpuset, and then set the affinity of both your threads to this cpu set.

rgouicem
  • 351
  • 2
  • 3
  • `cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(sched_getcpu(), &cpuset); if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) == 0) { if (pthread_setaffinity_np(std_thread.getNativeHandle(), sizeof(cpu_set_t), &cpuset) == 0) { std::cout << "Afinity ok!!!" << std::endl; } else { std::cout << "second thread set affinity failed." << std::endl; } } else { std::cout << "main thread set affinity failed." << std::endl; }` does not work(the "Afinity ok!!!" prints in the console but in htop the cpus are still random), thanks for the comment. –  Aug 15 '18 at 09:12
  • 1
    Are you sure that this is not due to another process running on another cpu ? While your program is running, try to get the affinity of your threads from another terminal with `taskset -a -p ` to see if the affinity was really changed. – rgouicem Aug 15 '18 at 09:41
  • I have issue the taskset command you gave me and the result for all the threads was: "current affinity mask: f". I have issue the command before and after the code was run, no change in the results. –  Aug 15 '18 at 09:44
  • I also added a `std::cout << "current cpu: " << sched_getcpu() << std::endl;` and the result is strange, i got 4 cores but sometimes the print result is "12". –  Aug 15 '18 at 09:50
  • Maybe my linux version is too old? Since i'm testing this code in a cheap linux vm host, the linux version is "GNU/Linux 2.6.32-042stab127.2 x86_64". –  Aug 15 '18 at 09:53
  • 1
    I would say that if it was not supported on this version of Linux, the syscall would return an error. I tried your updated code with a single thread looping, and the thread was pinned to a single cpu. BTW, could you update your code in the question ? – rgouicem Aug 16 '18 at 17:05
  • Thanks, i have update the code in the question. I also tested the code in a newer linux(GNU/Linux 4.4.0-98-generic x86_64) and the result was the same, htop show that both thread are on different cpus and they change once a while. –  Aug 17 '18 at 15:06
  • i have run the command "taskset -a -p " and the thread i have set the affinity(std_thread) results "pid 12837's current affinity mask: 4". The "CPU_SET" has been called with parameter 2. Is everything ok here? –  Aug 17 '18 at 15:11
  • I just executed your code replacing `std_thread.getNativeHandle()` by `pthread_self()` and adding an infinite loop at the end, and it works for me. Are you sure your `std_thread` has the correct value ? As for the value returned by `taskset`, it seems okay, since `4 = 0b100`, meaning core 2. You can add the `-c` flag to have a cpulist. – rgouicem Aug 18 '18 at 16:10