Thread: Forcing thread to run on specific processor

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    25

    Forcing thread to run on specific processor

    I am trying to run my threads on specified cores.


    Code:
    HANDLE hThreads[2];
    hThreads[0] = (HANDLE)_beginthread(threadn,0,NULL);
    hThreads[1] = (HANDLE)_beginthread(threadm,0,NULL);
    SetThreadAffinityMask(hThreads[1],3);

    I have some basic code, two threads, of which the second I want to run on a specific core.

    So I used "SetThreadAffinityMask" which is specifically for this as I understand.
    But for some reason it doesn't run it on the specific core but instead spreads it over the cpu1-3. (hthread0 doesn't do much so it can't use any resources).

    Is there anything else I should do/use to make it work?

    2. Can I use "SetThreadAffinityMask" with pthreads as well?

    3. If it were to work, and I would spawn say 10 threads on hthread1 would they all stay on the same core or would they be spread over all cores?
    Last edited by coderplus; 04-16-2012 at 04:13 AM.

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Note to mods: this is a Windows programming question, not C, although the example happens to be written in C.

    To answer, however ....

    Firstly, when a process starts, the system sets a process affinity mask which specifies what logical processors a process is allowed to run on. The thread affinity mask is, at most, a subset, of the process affinity mask (which in turn is a subset of the system affinity mask, which will typically be the set of all logical processors on the host). Before starting any threads, it is necessary to first check the process affinity mask using GetProcessAffinityMask() - which also retrieves the system affinity mask. Then compare the process affinity mask with the system affinity mask, and change the process affinity mas using SetProcessAffinityMask(). Then you will be able to set the thread affinity, as a subset of the process affinity mask.

    There are also various access rights that the running process needs in order to get or set the affinity masks (eg PROCESS_QUERY_INFORMATION and PROCESS_SET_INFORMATION).

    Note: things are a bit more involved that that if the host supports more than 64 logical processors, but the documentation for GetProcessAffinityMask() goes into that, so I won't bother here.


    It is not generally possible to use SetThreadAffinityMask() with pthreads(). You'll need to get information on how the particular pthreads library is implemented. But then yoru code will be specific to a particular implementation of pthreads. But, then again, you're converting the return value from _beginthread() to a HANDLE, which is more than was intended in the implementation of _beginthread() too ..... you lose nothing by trying, except potentially locking your code into one vendor's compiler and library.

    Generally, if you set a thread affinity, it will keep running on the particular cores specified corresponding to bits in that mask. If the affinity mask specifies more than one processor, then the threads will be distributed over those cores, and the scheduler may see fit to move threads around on those processors.

    It is generally considered a good idea, if you are going to play with thread affinities, to create all your threads in the main() thread, and immediately set their affinity masks.

    Generally, it is recommended to create threads, and allow the scheduler to decide what core(s) to put them on. The scheduler can probably do a better job than most programmers, because it has access to information about the system status.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    25
    Alright I tried it out.

    Code:
    DWORD SAM,TAN;
    GetProcessAffinityMask(hThreads[1],&SAM,&TAN);
    tp1 = SetProcessAffinityMask(hThreads[1],0);
    tp2 = SetThreadAffinityMask(hThreads[1],3);
    It failed, obviously. But what I didn't get was what was I supposed to fill in at GetProcessAffinityMask, the thread/s or the exe that is running?
    It returns a long number basically, is that correct?
    I also don't know how to set the right access rights.

    Could you give me a simple correct example for it?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Moved - as suggested.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The first argument of GetProcessAffinityMask() and of SetProcessAffinityMask() is the handle of a process, not a thread. Look up GetCurrentProcess() or OpenProcess().

    I don't have any simple correct code examples to offer, unfortunately. I remember some of the basic ideas, but have never tried to do such a thing in earnest.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    Apr 2012
    Posts
    25
    Oh, that is unfortunate.

    I have looked at the functions. But how do I even retrieve or know what to fill in as "HANDLE hProcess"?

    Do I use "GetCurrentProcess" for this? And in what form does it return a value, int/char? (if that is the right one to get the process handle)

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    According to the documentation for GetCurrentProcess() it returns a "pseudo-handle". That pseudo-handle can be converted into a "real" handle (with a value that is valid in all processes, for use as a handle to your particular process) using DuplicateHandle(). I would suggest using that "real handle" as the first argument of Get... or SetProcessAffinityMask().

    It might help if you look these functions up on MSDN, and follow the links to related functions.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to resume thread at the specific time instance?
    By qingxing2005 in forum Windows Programming
    Replies: 1
    Last Post: 01-21-2007, 12:28 AM
  2. Forcing buttons...
    By elfjuice in forum Windows Programming
    Replies: 2
    Last Post: 04-30-2005, 02:27 AM
  3. Forcing Cursor Redraw
    By PJYelton in forum Windows Programming
    Replies: 4
    Last Post: 07-07-2003, 07:07 PM
  4. Forcing an enum to int?
    By Sebastiani in forum C++ Programming
    Replies: 14
    Last Post: 11-03-2002, 12:11 PM
  5. Forcing 30 day break
    By gamegod3001 in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 10-05-2001, 11:25 PM