This is a column about POSIX threading programming. Based on the clarification of the concept, the author will give you a detailed account of the POSIX line libraries API. This article is the first article that will tell you about thread creation and cancellation.
One, thread creation
1. 1 Threads and processes
Relative to a process, a thread is a concept that is closer to the execution body, it can share data with other threads in the process, but has its own stack space and has a separate execution sequence. Threads and processes are introduced on the basis of serial programs to improve the concurrency of programs, thus improving program efficiency and response time. Threads and processes have advantages and disadvantages in use: the overhead of thread execution is small but not conducive to the management and protection of resources, while the process is the opposite. At the same time, threads are suitable for running on SMP machines, while processes can be migrated across machines.
1. 2 Creating Threads
POSIX creates threads through the pthread_create () function, and the API defines the following:
int pthread_create(pthread_t *
|
Unlike the fork () call to create a process, the thread created by Pthread_create () does not have the same execution sequence as the thread that calls Pthread_create (), but instead makes it run the Start_routine (ARG) function. The thread returns the created threading ID, and attr is the thread attribute set when the thread is created (see below). The return value of Pthread_create () indicates whether thread creation was successful. Although ARG is a variable of type void *, it can also be passed as a parameter of any type to the Start_routine () function, and start_routine () can return a return value of type void *, and this return value can also be of another type. and is obtained by Pthread_join ().
1. 3 Thread Creation Properties
The attr parameter in Pthread_create () is a struct pointer, and the elements in the structure correspond to the running properties of the new thread, mainly including the following: __detachstate, which indicates whether the new thread is out of sync with the other threads in the process. If set, the new thread cannot be synchronized with Pthread_join (), and the resource is freed on its own when exiting. The default is pthread_create_joinable state. This property can also be set with Pthread_detach () after the thread is created and run, and once set to the Pthread_create_detach state (whether set at creation or runtime), it cannot be restored to Pthread_create_ joinable status. __schedpolicy, represents the new thread scheduling strategy, mainly including sched_other (normal, non-real-time), SCHED_RR (real-time, rotation method) and Sched_fifo (real-time, first-in, first-out) three, the default is Sched_other, The latter two scheduling policies are only valid for super users. The runtime can be changed using over Pthread_setschedparam (). __schedparam, a struct SCHED_PARAM structure that currently has only one sched_priority integer variable representing the thread's run priority. This parameter is valid only if the scheduling policy is real-time (that is, SCHED_RR or SCHED_FIFO) and can be changed at run time through the Pthread_setschedparam () function, which defaults to 0. __inheritsched, there are two values to choose from: Pthread_explicit_sched and pthread_inherit_sched, which indicates that the new thread uses the explicitly specified schedule policy and schedule parameters (that is, values in attr). The latter represents the value that inherits the caller thread. The default is pthread_explicit_sched. __scope, which indicates the range of competing CPUs between threads, that is, the valid range of thread priorities. The POSIX standard defines two values: Pthread_scope_system and pthread_scope_process, which represent competing CPU time with all threads in the system, which indicates that only the threads in the same process compete with the CPU. Currently, Linuxthreads only implements the Pthread_scope_system value. There are some values in the pthread_attr_t structure, but they are not set using Pthread_create (). To set these properties, POSIX defines a series of property-setting functions, including PTHREad_attr_init (), Pthread_attr_destroy (), and pthread_attr_get associated with each property---/pthread_attr_set---function.
1. 4 thread-created Linux implementations
We know that the thread implementation of Linux is done outside the core, and the kernel provides the interface do_fork () to create the process. The kernel provides two system calls, __clone () and fork (), and eventually calls the Do_fork () kernel API with different parameters. Of course, to implement threads, there is no core support for shared data segments for multi-process (in fact, lightweight processes), so Do_fork () provides a number of parameters, including CLONE_VM (shared memory space), CLONE_FS (shared file system information), Clone_ Files (shared file descriptor tables), Clone_sighand (Shared signal handle table), and clone_pid (shared process ID, only valid for in-process, that is, process No. 0). When using the fork system call, the kernel calls Do_fork () without using any shared properties, the process has a separate runtime environment, and when the thread is created using Pthread_create (), all of these properties are eventually set to invoke __clone (). All of these parameters are passed to the kernel do_fork (), thus creating a "process" with a shared runtime environment, only the stack is independent, and is passed in by __clone (). Linux threads exist in the kernel in the form of lightweight processes, with separate process table entries, and all creation, synchronization, and deletion operations are performed in the Pthread library. The Pthread library uses a management thread (__pthread_manager (), each process independent and unique) to manage the creation and termination of threads, assigning thread IDs to threads, sending thread-related signals (such as cancel), while the main thread (Pthread_create () The caller passes the request information through the pipeline to the management thread.
Second, thread cancellation
2. 1 definition of thread cancellation
In general, a thread terminates automatically when its principal function exits, but it can also be forced to terminate because it receives a termination (cancellation) request from another thread.
2. 2 Thread Cancellation semantics
The method of thread cancellation is to Cheng the cancel signal to the target line, but how to handle the cancel signal is determined by the target thread itself, either by ignoring, or immediately terminating, or continuing to Cancelation-point (the cancellation point), depending on the cancelation state. The default processing that the thread receives the cancel signal (that is, the default state of the pthread_create () creation thread) is to continue running to the cancel point, which means to set a canceled state and the thread to continue running Exit only when running to Cancelation-point.
2. 3 Cancel Point
According to the POSIX standard, Pthread_join (), Pthread_testcancel (), pthread_cond_wait (), pthread_cond_timedwait (), sem_wait (), sigwait ( Functions such as read (), write (), and other system calls that cause blocking are cancelation-point, while other pthread functions do not cause cancelation actions. But Pthread_cancel's hand album claims that the C library function is not cancelation-point because the Linuxthread library does not combine well with the C library, but the cancel signal causes the thread to exit from the blocked system call and resets the EINTR error code , so you can call Pthread_testcancel () before and after a system call that needs to be cancelation-point, to achieve the target required by the POSIX standard, which is the following code snippet:
pthread_testcancel(); retcode = read(fd, buffer, length); pthread_testcancel();
|
2. 4 Considerations for Program Design
If the thread is in an infinite loop and the loop body does not have an inevitable path to the cancellation point, the thread cannot be terminated by a cancellation request from another external thread. Therefore, the Pthread_testcancel () call should be added to the required path on such a loop body.
2. 5 pthread functions related to thread cancellation
int Pthread_cancel (pthread_t thread)
Sends a terminating signal to thread, and returns 0 if successful, otherwise a value other than 0. Sending a success does not mean that thread will terminate. int pthread_setcancelstate (int state, int *oldstate)
Set the response of this thread to the CANCEL signal, state has two values: pthread_cancel_enable (default) and Pthread_cancel_disable, The signal is set to the cancled state and the cancel signal is ignored to continue running, if the old_state is not NULL then the original cancel state is saved for recovery. int pthread_setcanceltype (int type, int *oldtype)
Sets the execution time for this thread to cancel the action, type is evaluated by two: Pthread_cancel_deffered and pthread_cancel_asychronous, only if the cancel state is enabled, The signal is received after continuing to run to the next cancellation point and then exit and immediately perform the Cancel action (exit); Oldtype if not NULL, the value of the canceled action type that is shipped. void Pthread_testcancel (void)
Check if this thread is in the Canceld state, and if so, cancel the action, or return directly.
POSIX Threading Programming Guide (1)