[Linux] pthread learning notes

Source: Internet
Author: User

<Unix environment advanced programming (second edition)> thread learning P287-P297

 
# Include <pthread. h> // create thread int pthread_create (pthread_t * restrict TIDP, const pthread_attr_t * restrict ATTR, void * (* start_rtn) (void *), void * restrict Arg ); // The thread terminates void pthread_exit (void * rval_ptr); // The thread automatically exits int pthread_join (pthread_t tid, void ** rval_ptr); // other threads block itself, wait for TID to exit // The thread to clear void pthread_cleanup_push (void (* RTN) (void *), void * Arg); void pthread_cleanup_pop (INT execute );

Note:

1. Thread Creation

The Return Value of the pthread_create () function is 0, indicating that the creation is successful, and the thread ID is stored in the TIDP; if the failure occurs, the return value is non-zero and needs to be processed by the user. The errno value is not modified.

2. Thread termination

A. Calling exit, _ exit, and _ exit by any thread will lead to the termination of the entire process;

B. There are three ways to exit a single thread:

1> return is used in start_rtn (), and the return value is the thread exit code;

2> it is canceled by other threads of the same process using pthread_cancel;

3> the thread itself calls pthread_exit ();

Note: The pthread_join (pthread_t tid, void ** rval_ptr) function blocks the calling thread until the TID thread terminates and exits through the above three methods, and return/pthread_exit () the corresponding thread exit code rval_ptr is set, and the thread that pthread_cancel () is canceled sets the exit code to pthread_canceled.

3. Thread cleanupProgram(Thread cleanup handler)

3. A> pthread_cleanup_push () and pthread_cleanup_pop () are both macro definitions implemented in <pthread. h>. The specific implementation is as follows:

 
Pthread_cleanup_push and pthread_cleanup_pop are macros and must always be used in matching pairs at the same nesting level of braces. */# define pthread_cleanup_push (routine, ARG) \ do {\__ pthread_cleanup_class _ clframe (routine, ARG)/* remove a cleanup handler installed by the matching pthread_cleanup_push. if execute is non-zero, the handler function is called. */# define pthread_cleanup_pop (execute) \ _ clframe. _ setdoit (execute); \} while (0)

It can be seen that the {/} in Push/pop is one-to-one, so pthread_cleanup_push/POP () should also be one-to-one, otherwise compilation errors will occur.

3. B> when the thread executes one of the following operations, the cleanup function is called. thread_cleanup_push is implemented by the stack structure. Pay attention to the order in which the program is called.

1: When pthread_exit () is called, direct return does not start to clean up the function;

2: cancel the pthread_cancel () request accordingly;

3: When pthread_cleanup_pop () is called using the non-zero execute parameter;

Note that the pthread_cleanup_pop () parameter varies with the position of the statement.

Check thisCodeInstance. Note that the return or pthread_exit () locations are different, resulting in changes in the effect of different parameters of pthread_cleanup_pop.

# Include <pthread. h> void testpointersize () {void * tret; printf ("size of pointer in x86-64: % d \ n", sizeof (tret); // result is 8 in x86-64. // which is 4 in x86-32.printf ("size of int in x86-64: % d \ n", sizeof (INT); // result is 4 in x86-64. // which is also 4 in x86-32 .} void cleanup (void * Arg) {printf ("cleanup: % s \ n", (char *) Arg);} void * thr_fn1 (void * Arg) {printf ("thread 1 start \ n"); pthread_cleanup_push (cleanup ," Thread 1 first handler "); pthread_cleanup_push (cleanup," thread 1 second handler "); If (ARG) Return (void *) 1); // Arg! = 0, return here. // return here will not triger any cleanup. pthread_cleanup_pop (0); pthread_cleanup_pop (1); Return (void *) 2); // will not run this} void * thr_fn2 (void * Arg) {printf ("thread 2 start \ n"); pthread_cleanup_push (cleanup, "thread 2 first handler"); pthread_cleanup_push (cleanup, "thread 2 second handler "); pthread_cleanup_pop (0); pthread_cleanup_pop (1); Return (void *) 2); // return here can triger cleanup second handler;} void * thr_fn3 (void * Arg) {printf ("thread 3 Start \ n"); pthread_cleanup_push (cleanup, "thread 3 first handler"); pthread_cleanup_push (cleanup, "thread 3 second handler"); If (ARG) pthread_exit (void *) 3); // pthread_exit () here will triger both cleanup first & Second handler. pthread_cleanup_pop (1); pthread_cleanup_pop (0); pthread_exit (void *) 3); // wont run this} void * thr_fn4 (void * Arg) {printf ("thread 4 start \ n"); pthread_cleanup_push (cleanup, "thread 4 first handler"); pthread_cleanup_push (cleanup, "thread 4 second handler "); pthread_cleanup_pop (1); pthread_cleanup_pop (0); pthread_exit (void *) 4); // pthread_exit () here will triger cleanup second handler .} int main (void) {testpointersize (); int err; pthread_t tid1, tid2, tid3, tid4; void * tret; err = pthread_create (& tid1, null, thr_fn1, (void *) 1); err = pthread_join (tid1, & tret); printf ("thread 1 exit code % d \ n", (INT) tret ); err = pthread_create (& tid2, null, thr_fn2, (void *) 2); err = pthread_join (tid2, & tret ); printf ("thread 2 exit code % d \ n", (INT) tret); err = pthread_create (& tid3, null, thr_fn3, (void *) 3 ); err = pthread_join (tid3, & tret); printf ("thread 3 Exit code % d \ n", (INT) tret); err = pthread_create (& tid4, null, thr_fn4, (void *) 4); err = pthread_join (tid4, & tret); printf ("thread 4 exit code % d \ n", (INT) tret );}

Running result:

 
[Root @ Hello testdata] #. /test size of pointer in x86-64: 8 size of int in x86-64: 4 thread 1 startthread 1 exit code 1 thread 2 startcleanup: thread 2 first handlerthread 2 exit code 2 thread 3 startcleanup: thread 3 second handlercleanup: thread 3 first handlerthread 3 Exit code 3 thread 4 startcleanup: thread 4 second handlerthread 4 exit code 4

The test procedure is summarized as follows:

1> the return between push and Pop will prevent the cleaning program from being triggered;

2> return after pop. The pop parameter determines whether to trigger the cleaning program. The non-zero parameter is triggered and the zero parameter is not triggered;

3>Pthread_exit () between push and Pop will trigger all cleanup functions;

4> when pthread_exit () is located after pop, the pop parameter determines whether to trigger the cleanup program;

In fact, the above four situations only test and verify the three conditions described in Article 3. B to deepen understanding.

 

References:

1. POSIX Thread Programming Guide (4)

2. <Unix environment advanced programming (version 2nd)> P295-296 Program

3. Details about pthread_cleanup_push ()/pthread_cleanup_pop ()

4. Vim column editing instance (Mark record) in Linux)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.