Thread: Linux Putting my children to sleep with futex!?

  1. #16
    Registered User
    Join Date
    Feb 2009
    Posts
    10
    Quote Originally Posted by brewbuck View Post
    On Linux at least, pthread mutexes can be shared between processes. You have to initialize the mutex within a shared memory segment (something you already have), and set the attributes with:

    Code:
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    As far as I know, you can't currently do this with condition variables, only mutexes.
    Interesting, I didn't know you could set a mutex to span multiple processes... I always thought the pthread library was more specific to the threads located in a single process. But I guess now that I think about the use of sem_init etc... and that it can span processes while being included in the pthread library it makes sense. Thanks

  2. #17
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Abs View Post
    Interesting, I didn't know you could set a mutex to span multiple processes... I always thought the pthread library was more specific to the threads located in a single process. But I guess now that I think about the use of sem_init etc... and that it can span processes while being included in the pthread library it makes sense. Thanks
    Well, consider what a pthread_mutex actually is. It looks kind of like this:

    Code:
    struct pthread_mutex_t
    {
        volatile sig_atomic_t spinlock;
        int lock_count;
        int wait_count;
        wait_queue_head *waiting_threads;
    };
    When a thread or process attempts to lock the mutex, it first gains the spinlock. Then it checks the lock count -- if the lock is unlocked, it increments the count, then unlocks the spinlock. On the other hand, if the lock was locked, the process puts itself on the wait queue, increments the wait count, then unlocks the spinlock while simultaneously sleeping. On Linux, that last step is achieved with a futex.

    When the process holding the mutex unlocks it, it first locks the spin lock, then decrements the lock_count. If the lock_count becomes zero, it checks the wait count (while still holding the spinlock). If it's greater than zero, it dequeues all the processes on the wait queue and wakes them up, sets the wait_count to zero, decrements the lock_count, then unlocks the spinlock.

    Being able to do this across processes depends on having a method of placing other processes on the wait queue, and telling them to wake up. On Linux, this is done with futexes. Not all implementations of pthreads support inter-process mutexes, but Linux does.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #18
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Does anyone forsee any problem with this...
    Not sure what "this" is at this point

    You can continue to use signals, just replace the signal handler with "g_time_to_die = 1". Then the controlling loop in dispatcher() would be "while (!g_time_to_die)", or something like that.

    If you just call _exit() in your signal handler, that's not a "clean" way to die (no atexit handlers are called, resources aren't manually released, etc...). A clean termination would be ideal.

    gg

  4. #19
    Registered User
    Join Date
    Feb 2009
    Posts
    10
    yeah...sorry about the vagueness of "this". I was referring to just having the signal handler make the child call _exit when it recieves the signal and then resetting the shared counter back to 0.

    I know it would be better if they exited normally, but my dispatcher isn't in a loop. Each request that comes in is it's own process and then exits... So the dispatcher right now just takes the request (as the child) determines what kind of request it is, calls the correct function to handle the request and thats about it. So short of checking g_time_to_die between various points of all the functions after my dispatcher is called I'm not seeing another way to truly interrupt and cleanly have the childred cleanly exit.

    I was also unaware of the atexit function (thanks, that will come in useful later on), and so am not calling any other functions on normal exit. I did notice that _exit closes open file descriptors etc.. which should be enough for what the children are doing.

    As of now I've been able to successfully load the crap out my hobbled together code and no crashes/problems at all (knock on wood). I may still use a semaphore to wait for the max processes to back down so there is an open slot, and if it waits too long then send the kill with the assumption that all of the currently running children are hosed. But thats for later.

    Thank you both for all of the great information and insight into what was happening. I don't think I ever would have thought it was problem with my signal handler. Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Which distribution of Linux should I get?
    By joshdick in forum A Brief History of Cprogramming.com
    Replies: 50
    Last Post: 01-19-2003, 09:26 AM
  2. Linux for Windows!
    By Strut in forum Linux Programming
    Replies: 2
    Last Post: 12-25-2002, 11:36 AM
  3. Linux? Windows Xp?
    By VooDoo in forum Linux Programming
    Replies: 15
    Last Post: 07-31-2002, 08:18 AM
  4. Linux Under Windows
    By Strut in forum Linux Programming
    Replies: 3
    Last Post: 05-27-2002, 08:09 PM
  5. linux vs linux?
    By Dreamerv3 in forum Linux Programming
    Replies: 5
    Last Post: 01-22-2002, 09:39 AM

Tags for this Thread