I have a detailed introduction to "multi-threaded programming under Linux" on the Internet. I have read it carefully and I have gained a lot!
Multithreading model in Linux:
Available getconf-A |
Grep gnu_libpthread_version: My machine uses nptl 2.3.4 developed by RedHat.
A simple description of pthread implementation:
The implementation of pthread is achieved by calling clone. By the way, the difference between fork, vfork, and clone (the do_fork function is called at the underlying layer ):
1. fork: full copy, deep copy, using copy-on-write technology. The Parent and Child processes are executed simultaneously and are not blocked. "It is the only way for the UNIX kernel to create a new process (excluding the exchange process, INIT process, and page genie process, these processes are created in a special way by the kernel as part of the self-lifting process )." ---- From section 8.3 of UNIX advanced environment programming
2. vfork: shared address space. The sub-process runs first until it calls exit or exec and the parent process runs.
3. Clone: customizes the creation process (or thread ). In Linux, pthread is implemented by calling clone. Shared Memory (clone_vm), file system access count (clone_fs), file descriptor table (clone_files), and signal processing method (clone_sighand ).
Pthread function family
A lot of functions can be used directly by man to find out what the function is doing. Here I just want to talk about it:
1.Pthread_exitUsed with pthread_join to obtain the return code of the subthread:
Thread abort, which can be: return in the thread function; cancel is dropped by another thread in the same process; the thread calls the pthread_exit function.
1.1 thread function return:
A * fun () {A * a = new A (); return a ;}< br/> A * a; <br/> pthread_join (pthread, (void **) (& ));
1.2 canceled by cancel:
Call pthread_cancel. A non-blocking call should send a cancel signal to the kernel level. The target thread determines how to handle the cancel signal: terminate immediately, ignore it, and continue running to cancel_point (default ).
Based on POSIX standards, pthread_join (), pthread_testcancel (), pthread_cond_wait (),
Pthread_cond_timedwait (), sem_wait (), sigwait () and other functions, as well as read (), write (), and other system calls that will cause blocking are all cancelation-point, other pthread functions do not cause cancelation. However, the pthread_cancel manual page claims that, due to the poor combination of the linuxthread Library and the C library, the current C library functions are not cancelation-point;HoweverCANCELThe signal causes thread Resistance The plug-in is exited in the System Call andEINTRError CodeTherefore, you can call pthread_testcancel () before and after a system call that needs to be called as a cancelation-point to meet the POSIX standard requirements, that is, the following code segment:
Pthread_testcancel (); retcode = read (FD, buffer, length); pthread_testcancel ();
If cancel is dropped, pthread_join returns pthread_cancelled (-1)
Void * fun () {pthread_testcancel () ;}< br/> pthread_cancel (pth); <br/> int * p = new int; <br/> pthread_join (pth, (void **) (p ));
1.3 call pthread_exit
Pthread_exit (void *) 10 );
2.Set the second parameter pthread_create for attributes when a thread is created.
Pthread_attr_t: mainly includes scope, whether to detach, stack address, stack size, priority, and so on.
Typedef struct <br/>{< br/> int detachstate; thread separation status <br/> int schedpolicy; Thread Scheduling Policy <br/> struct sched_param schedparam; thread Scheduling parameters <br/> int inheritsched; thread inheritance <br/> int scope; thread scope <br/> size_t guardsize; alert buffer size at the end of the thread stack <br/> int stackaddr_set; stack address set <br/> void * stackaddr; thread stack location <br/> size_t stacksize; thread stack size <br/>} pthread_attr_t;(See multi-threaded programming-thread attributes)
2.1 Scope:
Pthread_attr_setscope (& attr,
PTHREAD_SCOPE_SYSTEM | PTHREAD_SCOPE_PROCESS );
The correct understanding here should be to define the scope (system level or process level) for The thread to compete for resources: the contentionscope attribute may have The values
PTHREAD_SCOPE_SYSTEM, signifying system scheduling contention scope, or
PTHREAD_SCOPE_PROCESS, signifying process scheduling contention scope
2.2 separation or not:
The separation status of a thread determines how a thread terminates itself. Default non-separated status (PTHREAD
In _ CREATE_JOINABLE), only when the pthread_join function returns, the creation thread is terminated and the system resources occupied by the thread can be released. Otherwise, memory leakage may occur. In the separated state (PTHREAD_CREATE_DETACHED), the thread stops running and immediately releases system resources without waiting by other threads.
Note: In the separation state, the thread may end before the pthread_create function returns, and may hand over the thread number and system resources to other threads, the thread id returned by pthread_create is incorrect. Thread synchronization mechanism can be used to avoid this situation!
2.3 stack address:
You can set the thread stack to run in the stack address you have applied.
2.4 stack size:
Ulimit
-A can see the size limit of the stack. Setting the stack size in the thread attribute can break this limit. Correspondingly, there is also the pthread_attr_setguardsize function that sets the alert buffer size.
2.5 Priority (scheduling parameter ):
You can use the sched_get_priority_max function and sched_get_priority_min function to obtain the maximum and minimum priority values supported by the system. If you are not writing real-time programs, we do not recommend that you modify them. Because the scheduling policy is a very complicated task. improper use may lead to program errors and deadlocks. For example, setting different priority levels for threads in multi-threaded applications may lead to priority inversion due to resource sharing.
3.PthreadTSD (thread-specific data)
The private global variable of the thread (different addresses with the same name ). Valid only in a thread, but can be used across multiple functions. For example, a common errno is a TSD. Pthread_key_delete is used to delete a key. The memory occupied by this key will be released, but it does not release the resources occupied by the thread data associated with this key, the destructor function defined in pthread_key_create is not triggered. For details, see posix Thread Programming Guide.
Pthread instance analysis
1, Memory leakage:
Source code:
Char * url = new char [100]; <br/> int ret = pthread_create (& pt, NULL, sendurl, url ); <br/> void * sendurl (void * url) <br/>{< br/> char * purl = (char *) url; <br/> // do something <br/> delete [] purl; <br/> return NULL; <br/>}
Analysis: Obviously, there is a memory leak, neither setting the thread separation attribute nor using pthread_join to wait for the thread to end.
Solution:
You can set the separation attribute of the thread:
Pthread_t pt; <br/> pthread_attr_t attr; <br/> pthread_attr_init (& attr); <br/> pthread_attr_setdetachstate (& attr, PTHREAD_CREATE_DETACHED ); <br/> int ret = pthread_create (& pt, & attr, CntServer: SendUrl, url); <br/> pthread_attr_destroy (& attr );
Or achieve self-separation:
In the thread function, pthread_detach (pthread_self ());
Note: The effect of multiple
Pthread_detach () callon the same target thread is unspecified.
Or usePthread_joinWait
Pthread_join (pt,
NULL );
2, Stop the subthread of an endless loop
Set how the thread processes the cancel Signal
Pthread_setcancelstate (PTHREAD_CANCEL_ENABLE,
NULL); // allows the thread to exit
Set immediate cancellation or delayed cancellation
Pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,
NULL); // The setting is canceled immediately.
Pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED,
NULL); // sets the delay to cancel
Note: You need to set cancel_point to cancel the delay (you can add pthread_testcancel)
Use pthread_cancel to send the cancel Signal
Pthread_cancel (pthread );