Linux under the use of C to develop multithreaded programs, Linux system multithreading following the POSIX thread interface, known as Pthread.
#include <pthread.h>
int pthread_create (pthread_t *restrict TIDP,
const pthread_attr_t *restrict,
void * (*START_RTN) (void),
void *restrict arg); |
returns:0 if OK, error number on failure |
A new restrict-decorated pointer is added to the C99: A pointer decorated by restrict is the first way to access the object that the pointer points to, only when the second pointer is based on the first. Access to an object is limited to a pointer expression that is based on a restrict modification. Pointers decorated by restrict are primarily used for function parameters or point to the memory space allocated by malloc (). The Restrict data type does not change the semantics of the program. The compiler can better optimize certain types of routines by making restrict-modified pointers the only way to access objects.
The
First parameter is a pointer to the thread identifier. The
The second parameter is used to set the thread properties. The
third parameter is the starting address of the thread-running function. The
last parameter is the parameter of the running function.
In this program, our function thread does not require arguments, so the last argument is set to a null pointer. The second argument is also set to a null pointer, which will generate the thread for the default property. When the line Cheng is created, the function returns 0, if not 0, the creation thread fails, and the common error return code is eagain and einval. The former indicates a system restriction to create a new thread, such as an excessive number of threads, which indicates that the second parameter represents an illegal thread property value. After the creation of the thread succeeds, the newly created thread runs the function of parameter three and parameter four, and the original thread continues to run the next line of code.
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h >
#include <unistd.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 *thread (void *arg)
{
printids ("New Thread:");
return ((void *) 0);
}
int main ()
{
int temp
if (temp=pthread_create (&ntid,null,thread,null))!= 0)
{
printf ("Can ' t create thread:%s\n", strerror (temp));
return 1;
}
Printids ("Main thread:");
Sleep (1);
return 0;
}
Modify a program on the APUE2 and compile it.
Result Error:
PTHREAD.C: (. text+0x85): References not defined for ' pthread_create '
Because the Pthread library is not the default library for the Linux system, you need to use the library LIBPTHREAD.A when you connect, so when you create a thread using Pthread_create, you add the-lpthread parameter to the compilation:
Gcc-o Pthread-lpthread PTHREAD.C
This is a column about POSIX threading programming. The author, on the basis of clarifying concepts, will give you a detailed account of the POSIX line threading API. This is the first article that will tell you about the creation and cancellation of threads.
1. 1 Threads and processes
In relative processes, 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. The introduction of threads and processes on the basis of serial programs is to improve the concurrency of programs, thus increasing the efficiency of program operation and response time.
Threads and processes have advantages and disadvantages in their use: Thread execution costs are small but not conducive to resource management and protection; The process is the opposite. At the same time, threads are suitable for running on SMP machines, while processes can migrate across machines.
1. 2 Creating Threads
POSIX creates threads through the pthread_create () function, which is defined as follows:
int pthread_create (pthread_t * thread, pthread_attr_t * attr,
void * (*start_routine) (void *), void * arg)
|
Unlike a fork () call to create a process, the thread created by Pthread_create () does not have the same sequence of execution as the thread that invokes the Pthread_create (), but rather makes it run the Start_routine (ARG) function. Thread returns the threads ID created, and attr is the thread attribute set when the thread is created (see below). The return value of Pthread_create () indicates whether the thread creation was successful. Although ARG is a variable of type void, it can also be passed to the Start_routine () function as an argument of any type, and Start_routine () can return the return value of a void * type, and the return value can be other types, and obtained by Pthread_join ().
1. 3 Thread Creation Properties
The attr parameter in Pthread_create () is a structure pointer, and the elements in the structure correspond to the running properties of the new thread, including the following:
__detachstate, which indicates whether the new thread is out of sync with other threads in the process, if the new thread cannot synchronize with the Pthread_join (), and releases the resource that it occupies when exiting. The default is the 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 state.
__schedpolicy, which represents the scheduling strategy for new threads, mainly includes Sched_other (normal, Non-real time), SCHED_RR (real-time, rotary) and Sched_fifo (real time, first in first out) three kinds, the default is Sched_other, The last two scheduling policies are valid only for Superuser. The runtime can be changed using Pthread_setschedparam ().
__schedparam, a struct SCHED_PARAM structure, currently has only one sched_priority integer variable that represents the running priority of the thread. This parameter is valid only if the scheduling policy is real-time (i.e. SCHED_RR or SCHED_FIFO) and can be changed at run time by the Pthread_setschedparam () function, which defaults to 0.
__inheritsched, there are two values to choose from: Pthread_explicit_sched and pthread_inherit_sched, which means that the new thread uses an explicit scheduling policy and a schedule parameter (that is, a value in attr). The latter represents the value of the inherited caller thread. The default is pthread_explicit_sched.
__scope, which represents the range of competing CPUs between threads, that is, the valid range of thread precedence. 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 means that only the CPU is competing with threads in the process. At present, the Linuxthreads only implements a 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 that are 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 of the core, providing the interface for creating the process do_fork (). The kernel provides two system calls __clone () and fork (), which eventually invoke the Do_fork () kernel API with different parameters. Of course, in order to implement threads, there is no core for multiple processes (in fact, lightweight processes) to share data segment support is not, therefore, 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, valid only for the nuclear process, that is, the No. 0 process). When using the fork system call, the kernel calls Do_fork () does not use any shared properties, the process has a separate running environment, and when the thread is created using Pthread_create (), all of these properties are eventually set to invoke __clone (). These parameters are all passed to Do_fork () in the kernel, thus creating a "process" that has a shared running environment in which only the stack is self-contained and passed by __clone ().
Linux threads exist in the kernel as lightweight processes, have separate process table entries, and all creation, synchronization, and deletion operations are performed in the Pthread library. The Pthread library uses an administrative thread (__pthread_manager (), each process is independent and unique) to manage the creation and termination of threads, assign thread IDs to threads, send thread-related signals (such as cancel), and the main thread (Pthread_create () The caller passes the request information to the management thread through a pipe.
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 (cancel) request from another thread.
2. 2 Semantics for thread cancellation
The method of threading cancellation is to Cheng the cancel signal to the target line, but how to process the cancel signal is determined by the target thread itself, or by ignoring, or immediately terminating, or continuing to Cancelation-point (the cancellation point), depending on the cancelation state.
The thread receives the cancel signal's default processing (that is, pthread_create () The default state of creating the thread) is to continue to run to the cancel point, that is, set a canceled state, the thread continues to run, Only when you run to Cancelation-point will you quit.
2. 3 Cancellation 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 so on, can cause blocking system calls to be cancelation-point, while other pthread functions do not cause cancelation actions. But Pthread_cancel's hand album claims that because the Linuxthread library is not well combined with the C library, the C library function is not cancelation-point at the moment, but the cancel signal exits the thread from the blocked system call and resets the EINTR error code , you can call Pthread_testcancel () before and after a system call that needs to be cancelation-point to achieve the desired goal of the POSIX standard, which is the following code snippet:
Pthread_testcancel ();
Retcode = Read (fd, buffer, length);
Pthread_testcancel (); |
2. 4 Program Design Considerations
If the thread is in an infinite loop and the loop body does not have the necessary path to the cancellation point, the thread cannot be terminated by the cancellation request of an external thread. Therefore, the Pthread_testcancel () call should be added to the necessary path of such a loop body.
2. 5 The Pthread function associated with the thread cancellation
int Pthread_cancel (pthread_t thread)
Sends an abort signal to the thread thread and returns 0 if successful, otherwise it is not a 0 value. Sending 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, respectively, the signal is set to cancled state and the cancel signal is ignored, and the old_state is deposited in the original cancel state if it is not null for recovery.
int pthread_setcanceltype (int type, int *oldtype)
Sets the timing for this thread to cancel the action, with type two values: Pthread_cancel_deffered and pthread_cancel_asychronous, only if the cancel state is enabled. Each indicates that the signal continues to run to the next cancellation point and then exits and immediately performs the Cancel action (exit), and oldtype the canceled action type value if it is not null.
void Pthread_testcancel (void)
Check whether this thread is in the Canceld state, if it is, cancel the action, or return directly.