Linux/unix Threads (1)

Source: Internet
Author: User
Tags exit in terminates

Threads (1)

This article describes how to use multiple control threads to run multiple tasks in a single process environment.

All threads in a process are able to access the constituent parts of the process (such as the file descriptor and memory).

The thread contains the information necessary to represent the running environment within the process, including the thread ID of the process that identifies the thread, a set of register values, stacks, scheduling priorities and policies, a signal mask word, a errno variable, and thread-private data. All the information about the process is shared with all threads of the process, including the executable program text, the program's global memory and heap memory, the stack, and the file description descriptor.

Thread identity

The process ID is unique across the system. The ID of each thread. The thread ID is only valid in the process environment to which it belongs.

Threads in the thread. The type of thread ID is the pthread_t type because the POSIX standard is adopted on Linux threads, so, under different systems. The types of pthread_t are different. For example, under UBUNTN, it is the unsigned long type. In the Solaris system, it is the unsigned int type. In FreeBSD, it is a structural problem pointer. So you cannot use = = to interpret directly. And should use pthread_equal to infer.

#include <pthread.h>

Intpthread_equal (pthread_t t1, pthread_t T2);

Return value: Returns a value other than 0 if equal, otherwise 0.

Threads can be called by the

#include <pthread.h>

Pthread_tpthread_self (void);

The return value is the thread of the calling thread.

Thread creation

The create thread can call the Pthread_create function to create.

#include <pthread.h>

Intpthread_create (pthread_t *thread, const pthread_attr_t *attr,

void* (*start_routine) (void *), void *arg);

Return value: Returns 0 if successful, otherwise returns the error number

When Pthread_create successfully returns, the memory unit pointed to by the thread is set to the thread ID of the newly created thread.

attr parameters are used to customize various thread properties.

Set attr to NULL to create the default properties of the thread.

The newly created thread starts execution from the Start_routine function address, which has only one untyped pointer parameter arg. Assuming that you need to pass more than one argument to the Start_routine function, you need to put these parameters into a struct and then pass the address of the struct as an arg parameter.

When a thread is created, it does not guarantee which thread will execute first: whether it is a newly created thread or a calling thread. The newly created thread can access the process's address space and inherit the calling thread's floating-point environment and the signal mask Word. However, the thread's pending signal set is cleared.

The following program creates a thread and prints the process ID, the thread ID of the new thread, and the thread ID of the initialization thread.

#include <stdio.h> #include <stdlib.h> #include <pthread.h>pthread_t ntid;void printids (const char *s ) {    pid_t       pid;    pthread_t   tid;    PID = Getpid ();    Tid = Pthread_self ();    printf ("%s pid%u tid%u (0x%x) \ n", s, (unsigned int) PID,      (unsigned int) tid, (unsigned int) tid);} void * THR_FN (void *arg) {    printids ("New Thread:"); return ((void *) 0);} void Err_quit (const char* FMT, ...) {printf ("%s\n", FMT); exit (1);} int main (void) {    int     err;    Err = pthread_create (&ntid, NULL, THR_FN, NULL);    if (err! = 0)        err_quit ("Can ' t create thread:%s\n", strerror (Err));p rintids ("Main thread:");    Sleep (1);    Exit (0);}

Compile:

The pthread Library is not the default library for Linux systems and requires a static library LIBPTHREAD.A when connected. So when you use Pthread_create () to create a thread and call the Pthread_atfork () function to establish a fork handler, you need to link the library.

GCC Creatthread.c–lpthread

Operation and output:

./a.out

Main thread:pid2846 tid 3079362240 (0xb78b56c0)

New Thread:pid 2846 tid 3079359344 (0xb78b4b70)

The main thread needs to hibernate, or the entire process may be terminated before the new thread enters execution. The new thread obtains its own thread ID through pthread_self () instead of being read from the shared memory or receiving it from the thread's startup routine. The Pthread_create function returns the ID of the new thread with the first number of parameters. In this example. The new thread ID is placed in the ntid, but assuming that the new thread executes before the primary call Pthread_create returns, the newly created thread sees the uninitialized Ntid content.

Thread termination

Assume that any thread in the process calls Exit,_exit or _exit. Then the whole process will be terminated. Once similar, assume that the default action of the signal is to terminate the process. Then, sending the signal to the thread terminates the entire process.

However, threads can exit in the following three ways:

1. Threads are simply returned from the startup routine. The return value is the thread's exit code

2. Threads can be canceled by other threads in the same process

3. Thread Call Pthread_exit

Pthread_exit function:

#include <pthread.h>

Voidpthread_exit (void *retval);

RetVal is an untyped pointer, similar to a single parameter passed to the start routine. Other threads in the process can access the pointer by calling the Pthread_join function.

#include <pthread.h>

Intpthread_join (pthread_t thread, void **retval);

Return value: Returns 0 if successful, otherwise returns the error number

The thread that calls the Pthread_join function is blocked until the specified thread calls Pthread_exit, returns from the startup routine, or is canceled.

Assume that the thread is simply returning from its startup routine. The retval will include a return code. Assume that the thread is canceled. retval The specified memory cell is set to pthread_canceled.

#include <stdio.h> #include <stdlib.h> #include <pthread.h> void * THR_FN1 (void*arg) {printf ("Thread 1    Returning\n "); return ((void *) 1);    void * THR_FN2 (void*arg) {printf ("Thread 2 exiting\n"); Pthread_exit ((void *) 2);} Voiderr_quit (const char* FMT, ...)    {printf ("%s\n", FMT); Exit (1);}    int main (void) {int err;    pthread_t Tid1, Tid2;     void *tret;    Err = Pthread_create (&tid1, null,thr_fn1, NULL);     if (err! = 0) {err_quit ("can ' t create thread 1:%s\n", strerror (err));    } err = Pthread_create (&tid2, null,thr_fn2, NULL); if (err! = 0) err_quit ("Can ' t create thread 2:%s\n", strerror (Err)); err = Pthread_join (TID1, &tret); if (err! =    0) Err_quit ("Can ' tjoin with thread 1:%s\n", strerror (err));    printf ("Thread 1 ExitCode%d\n", (int) tret);    Err = Pthread_join (Tid2,&tret);    if (err! = 0) err_quit ("Can ' tjoin with thread 2:%s\n", strerror (err)); printf ("Thread 2 ExitCode%d\n", (iNT) Tret); Exit (0);}

Execution and output:

Thread 2 exiting

Thread 1 Returning

Thread 1 exit code 1

Thread 2 exit code 2

It can be seen that when a thread exits by calling Pthread_exit or simply returns from the startup routine, other threads in the process can get the exit state of the thread by calling the Pthread_join function.

The Pthread_exit and pthread_create function's untyped pointer parameters can pass the address of a complex structure. Singular the memory callers used by the structure must still be valid after the call is finished.

Ability to allocate stack structures using global structures or malloc functions.

Threads can request cancellation of other threads in the same process by calling the Pthread_cancel function.

#include <pthread.h>

int Pthread_cancel (pthread_t thread);

Return value: Returns 0 if successful, otherwise the error number is returned.

By default, the Pthread_cancel function causes threads identified by thread to behave as if they had called the Pthread_exit function with the pthread_canceled, but the thread can choose to ignore the cancellation mode or control the cancellation.

A thread can schedule a function to be called when it exits, similar to the function that the process can use to call when the process exits with the atexit function. This function becomes a thread cleanup handler.

Threads can establish multiple cleanup programs. The handler is logged in the stack. This means that they run in the opposite order of their registration.

#include <pthread.h>

Voidpthread_cleanup_push (void (*routine) (void *), void *arg);

Voidpthread_cleanup_pop (int execute);

The cleanup function is called when the thread runs the following action, and the invocation is ARG. The order in which the cleanup function routine is called is arranged by the Pthread_cleanup_push function.

1. When calling Pthread_exit

2. When responding to a cancellation request

3. When calling Voidpthread_cleanup_pop with a non-0 execute parameter

Assuming that execute is 0, the cleanup function will not be called. In either case, Pthread_cleanup_pop deletes the cleanup handler that was established by the last Pthread_cleanup_push call.

For example, the following program shows how to use the thread cleanup handler.

#include <stdio.h> #include <stdlib.h> #include <pthread.h> 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");   printf ("Thread 1 push complete\n");   if (ARG) return ((void *) 1);   Pthread_cleanup_pop (0); Pthread_cleanup_pop (0); return ((void*) 1);} void * THR_FN2 (void *arg) {printf ("thread2 start\n");p Thread_cleanup_push (cleanup, "Thread 2 first handler");p Thread_ Cleanup_push (Cleanup, "Thread 2 second handler");p rintf ("Thread2 push complete\n"), if (ARG) pthread_exit ((void *) 2);p th Read_cleanup_pop (0);p thread_cleanup_pop (0);p thread_exit ((void*) 2);} void Err_quit (const char* FMT, ...) {printf ("%s\n", FMT); exit (1);} int main (void) {int err;pthread_t tid1, tid2;void *tret; Err =pthread_create (&tid1, NULL, Thr_fn1, (VO ID *) 1); if (err! = 0) err_quit ("Can ' t create thrEAD 1:%s\n ", strerror (err)); Err =pthread_create (&tid2, NULL, thr_fn2, (void *) 1), if (err! = 0) err_quit ("Can ' t create thread 2:%s\n", strerror (err ) Err =pthread_join (TID1, &tret), if (err! = 0) err_quit ("can ' t join with thread 1:%s\n", strerror (Err));p rintf ("thre  AD1 exit Code%d\n ", (int) tret); Err =pthread_join (Tid2, &tret); if (err! = 0) err_quit (" can ' t join with thread 2:%s\n ", Strerror (Err));p rintf ("Thread2 exit code%d\n", (int) tret); exit (0);}


Operation and output results such as the following:

Thread 2 Start

Thread 2 Push complete

Cleanup:thread 2 Second Handler

Cleanup:thread 2 First Handler

Thread 1 start

Thread 1 Push complete

Thread 1 exit code 1

Thread 2 exit code 2

It can be seen from the output that two threads are correctly started and exited, but only the second thread's cleanup handler is called, so if the thread is terminated by returning from its startup routine, its cleanup handler will not be called. Also note that the cleanup program is called in the reverse order that they were installed.

The separation state of a thread determines how a thread terminates itself. In the default case, the thread is non-detached, in such a case. The original thread waits for the thread to be created to end.

Only when the Pthread_join () function returns, the created thread is terminated, and talent frees up the system resources that it occupies.

The detach thread is not like this, and it is not being waited on by other threads. Self-execution was over. The thread is terminated. Releasing system resources immediately, Pthread_join calls to disconnected threads can produce a failure. Returns EINVAL. The Pthread_detach call can be used to get the thread into a detached state.

#include <pthread.h>

Intpthread_detach (pthread_t thread);

Return value: Returns 0 if successful, otherwise the error number is returned.

Linux/unix Threads (1)

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.