pthread newbie question

This is a discussion on pthread newbie question within the C Programming forums, part of the General Programming Boards category; I just started reading a pthreads tutorial and I was wondering why this: Code: #include <stdio.h> #include <pthread.h> void *th_go ...

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    pthread newbie question

    I just started reading a pthreads tutorial and I was wondering why this:
    Code:
    #include <stdio.h>
    #include <pthread.h>
    
    void *th_go (void *num) {
    	printf("thread %d\n",*(int*)num);
    	pthread_exit(NULL);
    }
    
    int main() {
    	pthread_t th[3];
    	int i;
    	void *ptr=(void*)&i;
    	for (i=0; i<3; i++) {
    		pthread_create(&th[i],NULL,th_go,ptr);
    	}	
    	return 0;			
    }
    Does this:
    Code:
    [root~/C] ./a.out
    thread 0
    thread 1
    thread 2
    [root~/C] ./a.out
    thread 1
    thread 2
    thread 2
    [root~/C] ./a.out
    thread 1
    thread 1
    [root~/C] ./a.out
    thread 0
    thread 1
    thread 2
    [root~/C] ./a.out
    thread 1
    thread 1
    [root~/C] ./a.out
    thread 0
    thread 1
    thread 2
    [root~/C] ./a.out
    thread 0
    thread 2
    thread 2
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You are taking the address of i, and then changing it in another thread. How can you possibly expect it to have a consistent value from one call to another?

    You could either cast the int into void *, or make sure that each pointer is unique (e.g. use malloc, or use an array with x elements, and pass the address of the relevant element to each thread).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    and then changing it in another thread.
    What?!#?!? Where?

    ...oh because it's a race with the for() ? Still, what about this:
    Code:
    [root~/C] ./a.out
    thread 1
    thread 0
    thread 2
    thread 2
    Last edited by MK27; 03-03-2009 at 07:52 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Hmmm...using pthread_exit() at the end of main seems to correct this.

    [edit] All that does is prevent the occasional fourth thread (which I don't know why it would ever happen). It is a race in the for loop. This is not like fork()!
    Last edited by MK27; 03-03-2009 at 08:01 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, obviously, you pass the address of i to the thread, then continuing in main thread, you modify i. What value will you get when you read it?

    Then you exit from the whole app without waiting for the threads to finish.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    Yes, obviously, you pass the address of i to the thread, then continuing in main thread, you modify i. What value will you get when you read it?

    Then you exit from the whole app without waiting for the threads to finish.
    Yep. But what leads to this (maybe one time in ten, without pthread_exit in main):
    Code:
    Creating 0
    thread 0
    Creating 1
    Creating 2
    thread 2
    thread 0
    thread 0       /* that's 4 */
    I added the "Creating" line in main. I presume the last two end up with zero because it's a stack variable and main already ended?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, what exactly are you asking?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    So, what exactly are you asking?
    Maybe I am getting slightly side-tracked, but it's curiosity that often gets me thru this new stuff. The only case that's unclear to me is that last one -- am I right to believe i ends up as 0 after main ends? But mostly, where does #4 come from?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I can't explain where #4 comes from... The value of i after the loop should not be zero, but who knows if it's not being used....

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,630
    Just like every malloc() should be paired with a free() - every call to pthread_create() should be paired with a call to either pthread_join() or pthread_detach(). The only exception is when you use a the PTHREAD_CREATE_DETACHED attribute.

    >> using pthread_exit() at the end of main seems to ... prevent the occasional fourth thread
    Well, in of itself, it prevents all the threads from being killed prematurely. Returning from main() is the same as calling exit() - which kills all running threads. pthread_exit() never returns, so you never return from main() and all other threads are allowed to run to completion.

    >> am I right to believe i ends up as 0 after main ends?
    Technically speaking, the behavior is undefined. To get an explanation for curiosity's sake, you would need to examine the generated assembly in context with the hardware it's running on (examine it in the debugger).

    Even though accessing the same memory location by multiple threads without synchronization is "undefined" - a simple unsynchronized read of an address shouldn't cause problems - as long as that address is valid. In this case, after returning from main() or calling pthread_exit(), i is not longer valid.

    gg

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Codeplug View Post
    Just like every malloc() should be paired with a free() - every call to pthread_create() should be paired with a call to either pthread_join() or pthread_detach(). The only exception is when you use a the PTHREAD_CREATE_DETACHED attribute.
    That makes sense (I'm not positive I believe you completely yet). Thanks for the notice.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    That makes sense (I'm not positive I believe you completely yet). Thanks for the notice.
    What part is it that you don't believe?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,630
    It's in the "RATIONALE" section for pthread_join and pthread_detach.
    http://www.opengroup.org/onlinepubs/...read_join.html

    gg

  14. #14
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,230
    Quote Originally Posted by matsp View Post
    Then you exit from the whole app without waiting for the threads to finish.
    Technically I think that's okay, because a return from main() implies a pthread_join() on any threads which are still running. I'm not 100% sure though.

    EDIT: Nope, I'm wrong.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pthread question
    By quantt in forum Linux Programming
    Replies: 7
    Last Post: 04-07-2009, 01:21 AM
  2. Stupid Newbie question
    By TimL in forum C++ Programming
    Replies: 4
    Last Post: 07-22-2008, 04:43 AM
  3. DrawText() and TextOut() newbie question
    By Cardassian in forum Windows Programming
    Replies: 3
    Last Post: 02-23-2003, 09:09 AM
  4. C prog newbie question
    By Draginzuzu in forum C Programming
    Replies: 1
    Last Post: 02-03-2003, 05:45 PM
  5. newbie class templates question
    By daysleeper in forum C++ Programming
    Replies: 2
    Last Post: 09-18-2001, 09:50 AM

Tags for this Thread


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