Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 11
Is this the best way to check for existence of a thread? I want to ensure thread A has completed before starting thread B. /* Globals */ pthread_t tid[25]; /* ...
  1. #1
    Just Joined!
    Join Date
    Jan 2009
    Location
    On the bay, Morecambe Bay.
    Posts
    15

    ESRCH confused



    Is this the best way to check for existence of a thread?
    I want to ensure thread A has completed before starting thread B.


    /* Globals */

    pthread_t tid[25];

    /* ....... */

    main()
    {. . . . . .
    /* get message from operator */
    /* parse message and pass to queue handler thread */
    }
    queueHandler()
    {
    . . . .
    printf("Check thread 11 not running\n");
    while(pthread_kill(tid[11],0) != ESRCH){
    perror("tid[11]");
    }
    if(pthread_create(&tid[7], NULL, myfunction, (void *)storage){
    perror("Thread creation fail");
    }
    }
    /* End of pseudo code */

    When running this segment, the thread does not leave the while loop, even though the thread 11 has not been created, and gives the perror message

    tid[11]: Illegal seek

    As the code progresses there will be times when thread 11 will have run and may or may not have exited. It is necessary to check the existence of the thread before thread 7 is created.
    When the above while() test is replaced with a single if() test the perror reports

    tid[11]: Success


    Any suggestions?

  2. #2
    Just Joined!
    Join Date
    Aug 2007
    Posts
    7
    What you're trying to do sounds a little sketchy to say the least. I wouldn't expect to be able to get this working reliably. I think you need to consider a different design.

    Can you tell us a bit more about what thread 11 and thread 7 are doing? Why is it important that thread 7 not be created while thread 11 is running?

    Speaking generally, you probably want to look at using some thread synchronization constructs to control this instead of checking to see if a particular thread is alive or not.

    **EDIT**

    Can't remember the function call off the top of my head, but there is a posix function to block a thread from running until another thread completes. So you could in your main thread, start thread 11, block your main thread until 11 finishes, and then create thread 7 and start it running.

  3. #3
    Just Joined!
    Join Date
    Mar 2006
    Posts
    29
    use pthread_join.
    This function waits for a thread to terminate before returning.

  4. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,499
    You haven't initialized the array, so all bets are off. In main, make sure you zero out the entire array:

    memset(&tid[0], 0, sizeof(tid));

    Secondly, use another name. The name tid is used for the system tap function tid(), so this could be a problem in C programs. Since you aren't using those libraries it isn't the case here, but just to make you name-aware...
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  5. #5
    Just Joined!
    Join Date
    Jan 2009
    Location
    On the bay, Morecambe Bay.
    Posts
    15

    pthread_t initialization?

    Thanks for the suggestions Guys.

    So far still no luck.

    If I change the name of the thread id's and initialize the array, the first run through the program stops with a sementation fault. If I initialize by creating and then joining an array of dummy threads (using thrid[]) then the program runs but I am not catching the condition when thread A does not exist and hence safe to start thread B, or vice versa.

    pthread_join, if I understand the man page correctly, should give the same result as pthread_kill(id,0) if the thread is question does not exist, i.e. non-zero return value and error code set to ESRCH. I have selected pthead_kill in preference to pthread_join because I want the target thread to complete normally (no cancellation points) before statring the next thread.

    My program is designed for an embedded control system that operates a mechanical test rig. Each mechanical function runs it's own thread. This way I can maintain multiple mechanical operations while servicing operator requests without polling. However, some functions must not run in parallel and consequently there is a need to wait for a task to complete. For example, operator says 'PUSH actuator'; actuator has indeterminate time to complete it's stroke. Operator can easily send next command to 'PULL actuator' before PUSH is complete. Embedded controller happily maintains a queue of instructions received and switches to the relevant case. The hurdle I am struggling to get over is, when 'PUSH' has not been called I was expecting to get an ESRCH error condition (or not as appropriate) to signal safe to launch PULL thread. Similarly, as time runs on the system can be in any state before a function is called. Before getting into trying to maintain a system state condition with globals and an awful barage of mutexes I thought the signalling approach would be the most elegant.

    The only way I can get this to work is by declaring pthread_t whatever[] as a local rather than global. The following works just fine:
    queueHandler(){
    pthread_t threadPush;
    Pthread_t threadPull;

    switch (nxtInstr){
    case PUSH:
    printf("Check PULL not running\n");
    while(pthread_kill(threadPull,0) == 0);
    printf("Activate PUSH \n");
    if(pthread_create(&thread_Push, NULL, push,(void *)storageX)
    perror("PUSH not started");
    break;
    case PULL:
    printf("Check PUSH not running\n");
    while(pthread_kill(threadPush,0) == 0);
    printf("Activate PULL \n");
    if(pthread_create(&thread_Pull, NULL, pull,(void *)storageY)
    perror("PULL not started");
    break;
    }

    This version works well, sending multiple PUSH/PULL commands will always work in sequence. If the pthread_t's are declared as globals, the program waits at each while loop.

    Can't understand what I'm missing for this to work.


    Cheers.

  6. #6
    Just Joined!
    Join Date
    Aug 2007
    Posts
    7
    You should be using mutexes for this.

    Frankly I fail to see how locking on even a few mutexes would be any uglier than this. A mutex for example will cleanly handle the situation where you have 3 controls that cannot be run in parallel. Your current solution will become quite verbose quite quickly should this situation arise.

    Depending on how you wrote your queue, it may still be possible for a pull and a push thread to start running at the same time. (Though I can't say for sure without seeing the rest of your application.)

  7. #7
    Just Joined!
    Join Date
    Jan 2009
    Location
    On the bay, Morecambe Bay.
    Posts
    15

    pthread alive or not?

    Appreciate the suggestion. If the application was as simple as I summarised, then mutexes are a solution. Surely it is more elegant to signal a thread and get a simple response, than it is to initialise a mutex, lock the mutex, test the mutex, and unlock the mutex??

    The real application has a DAQ thread (with mutexes and condition variables) to read, write and broadcast the analogue and digital I/O status, then there are (currently) two queue handler threads to manage parallel running test rig functions. main() is looking after client requests (i.e. instructions) and reporting back machine status for display on a remote operator console.
    Within each queue some functions, like the PUSH/PULL situation need to be run co-operatively. The list of operator instructions avaliable, at this stage of development, is 13 and will grow.

    As long as I declare pthread_t's as locals within a given queue handler then the PUSH/PULL scenario works well. I would like to understand why this doesn't work when the declarations are global. Initialising to 0 with memset, as suggested by Rubberman, does not solve the issue. I guess this is something to do with the opacity of the pthread_t type??

  8. #8
    Just Joined!
    Join Date
    Mar 2006
    Posts
    29
    I don't see in the man page the relation between pthread_join and pthread_kill. but you can return an error code from your thread to signal if it was completed correctly or not. It will be reported in the retval parameter of pthread_join.
    If the return code isn't a good one, don't launch the next thread, if it is good, launch the thread.

  9. #9
    Just Joined!
    Join Date
    Jan 2009
    Location
    On the bay, Morecambe Bay.
    Posts
    15
    Reference kernel.org man pages
    pthread_join(3)
    RETURN VALUE top
    On success, pthread_join() returns 0; on error, it returns an error number.

    ERRORS top
    . . .
    ESRCH No thread with the ID thread could be found.

    RETURN VALUE top
    On success, pthread_kill() returns 0; on error, it returns an error number,
    and no signal is sent.

    ERRORS top
    ESRCH No thread with the ID thread could be found.

    So if a thread does not exist a call to pthread_kill(whateverThread, 0) with a test for ESRCH should be true? Similarly, pthread_join(whateverThread, NULL) will give the same error code.

  10. #10
    Just Joined!
    Join Date
    Mar 2006
    Posts
    29
    Quote Originally Posted by nhutchin View Post
    So if a thread does not exist a call to pthread_kill(whateverThread, 0) with a test for ESRCH should be true? Similarly, pthread_join(whateverThread, NULL) will give the same error code.
    Yes

    But pthread_kill will kill immediatly the thread (this is not what you need), and pthread_join will wait for it until it terminates (with or without an error).
    That's why pthread_join is the best solution for you.

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •