[pthread] fails to create new thread even after old ones have terminated

This is a discussion on [pthread] fails to create new thread even after old ones have terminated within the C++ Programming forums, part of the General Programming Boards category; Hi, I have recently being learning and experimenting with pthread, and have noticed a weird behaviour (to me). I wrote ...

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183

    [pthread] fails to create new thread even after old ones have terminated

    Hi,
    I have recently being learning and experimenting with pthread, and have noticed a weird behaviour (to me). I wrote a simple testing program to show my question:
    Code:
    #include <pthread.h>
    #include <iostream>
    
    void *doNothing(void *);
    
    int main () {
            pthread_t nothingThread;
            int count = 0;
            while (!(pthread_create(&nothingThread, NULL, doNothing, NULL))) {
                    count++;
                    usleep(1000); //so threads won't be created faster than they are terminated
            }
            std::cout << count << std::endl;
    }
    
    void *doNothing(void *) {
            pthread_exit(NULL);
    }
    the program, when run, terminates almost immediately, printing "382" on my Linux machine, apparently after hitting some limit. I expected it to run indefinitely because every thread created terminates itself. Can someone please enlighten me on this question?

    Thank you very much

  2. #2
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    ps. a variation of this test program -
    Code:
    #include <pthread.h>
    #include <iostream>
    
    void *doNothing(void *);
    
    int main () {
            pthread_t nothingThread;
            int count = 0;
            while (!(pthread_create(&nothingThread, NULL, doNothing, NULL))) {
                    pthread_cancel(nothingThread);
                    count++;
                    usleep(1000);
            }
            std::cout << count << std::endl;
    }
    
    void *doNothing(void *) {
            for (;;);
    }
    gives the same result;

  3. #3
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    I think I found the solution to this problem.

    For a thread to clean up after itself, it has to be detached (as opposed to being joinable).

    eg.
    Code:
    #include <pthread.h>
    #include <iostream>
    
    void *doNothing(void *);
    
    int main () {
            pthread_t nothingThread;
            int count = 0;
            while (!(pthread_create(&nothingThread, NULL, doNothing, NULL))) {
                    pthread_detach(nothingThread);
                    count++;
                    usleep(1000);
            }
            std::cout << count << std::endl;
    }
    
    void *doNothing(void *) {
            pthread_exit(NULL);
    }

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    1. pthread_cancel does only work on special "cancellation points" (google will tell you what count as them)
    2. imo you have to call pthread_join after pthread_cancel to be sure it is canceled afterwards

    if you do not need true async thread cancellation I would suggest to signal a thread to end itself as often as possible. So you don't have to mess with thread properties, cancellation points and cleanup
    Last edited by pheres; 08-10-2007 at 12:49 PM.

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    thank you for your reply, google did lead me to this answer
    imo you have to call pthread_join after pthread_cancel to be sure it is canceled afterwards
    if a thread is detached, calling any pthread_* function "on" it is undefined. For detached threads, the best solution I found is to set a flag in a global variable immediately before it exits to signal other threads.
    if you do not need true async thread cancellation I would suggest to signal a thread to end itself as often as possible. So you don't have to mess with thread properties, cancellation points and cleanup
    hmm.. I don't quite understand that. I thought async cancellation gives no regard to cancellation points and cancel immediately?

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by cyberfish View Post
    hmm.. I don't quite understand that. I thought async cancellation gives no regard to cancellation points and cancel immediately?
    I found it easier (probably to a lack of knowledge, I couldn't get pthread_cancel to work under win32 and boost::threads have no cancel function at all) to let the thread end itself if I tell him to:

    Code:
    bool endThread = false;
    
    // create thread
    
    // run main program
    
    // end thread before exiting
    
    // lock 
    endThread = true;
    // unlock
    // join thread
    
    void* thread_fun(void*)
    {
       // lock
       cpy_endThread =  endThread;
       // unlock
    
       while(!cpy_endThread)
       {
           // thread work
    
          //    lock
          cpy_endThread =  endThread;
          // unlock
       }
    }

  7. #7
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    I can get pthread_cancel() to work under win32 like this:
    Code:
    // create thread
    
    // run main program
    
    // end thread before exiting
    
    // pthread cancel
    
    // pthread join
    
    void* thread_fun(void*)
    {
    
       while(true)
       {
           // thread work
           pthread_testcancel(); //set a cancellation point
       }
    }

  8. #8
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    I see, testcancel seems to be the missing part for me. But because I want to migrate to boost threads some day I let it the way it's done for now.

  9. #9
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    I just took a look at Boost threads and it looks very promising to me. Maybe I will switch too =)

    I was surprised that there isn't a function to cancel a thread though, seems important to me.

    Of course we can implement thread cancelling ourselves like you have done, but I would rather prefer a simpler and less error-prone solution.

    [edit]
    according to boost thread FAQ (http://www.boost.org/doc/html/thread/faq.html),
    9. Why isn't thread cancellation or termination provided?

    There's a valid need for thread termination, so at some point Boost.Thread probably will include it, but only after we can find a truly safe (and portable) mechanism for this concept.
    seems like we will just have to wait.
    [/edit]
    Last edited by cyberfish; 08-11-2007 at 11:39 AM.

  10. #10
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    the boost people say, as a response to many requests, that cancel will come, if a proper solution is found. they seem to say it for a good while now

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fork a child or create a thread?
    By zhoufanking in forum C Programming
    Replies: 3
    Last Post: 06-21-2008, 03:48 AM
  2. Multithreading
    By Cela in forum Windows Programming
    Replies: 13
    Last Post: 01-15-2003, 02:02 PM
  3. Your Best thread and your most stupid thread ??
    By jawwadalam in forum A Brief History of Cprogramming.com
    Replies: 13
    Last Post: 01-03-2003, 06:41 PM
  4. MFC Controls and Thread Safety :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 12-06-2002, 10:36 AM
  5. Multi-Thread Programming
    By drdroid in forum C++ Programming
    Replies: 6
    Last Post: 04-04-2002, 01:53 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21