Turn: http://hi.baidu.com/%BC%F2%B5%A5%BE%CD%BA%C3_88/blog/item/7cf34736f8e08e3d0a55a950.html
Multi-threaded programs are developed in C in Linux. multithreading in Linux follows the POSIX thread interface, which is called pthread.
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg); |
Returns: 0 if OK, error number on Failure |
The restrict modifier pointer is added in c99:
The modified pointer is the first and only method to access the object pointed to by the pointer. Only when the second pointer is based on the first one can the object be accessed. Access to objects is limited
In the pointer expression modified by restrict. The Pointer Modified by restrict is mainly used for function parameters, or pointed to by malloc ()
The allocated memory space. The restrict data type does not change the semantics of the program. The compiler can
The modified pointer is the assumption that the only method for accessing objects is better optimized for some types of routines.
The first parameter is the pointer to the thread identifier.
The second parameter is used to set the thread attributes.
The third parameter is the starting address of the thread-running function.
The last parameter is the parameter used to run the function.
In the following program, our functionthr_fn
No
Parameters are required, so the last parameter is set as a null pointer. We also set the second parameter as a null pointer to generate a thread with the default attribute. When the thread is successfully created, the function returns 0. If the value is not 0, the thread is created.
Failed. common error codes are eagain and einval. The former indicates that the system restricts the creation of new threads. For example, the number of threads is too large. The latter indicates that the second parameter indicates that the thread attribute value is invalid.
After the thread is successfully created, the newly created thread runs the function with parameters 3 and 4, 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 * thr_fn( void * arg ) {
printids( "new thread:" ) ;
return ( ( void * ) 0) ;
}
int main( ) {
int err;
err = pthread_create ( & ntid, NULL , thr_fn, NULL ) ;
if ( err ! = 0)
{
printf ( "can't create thread: %s/n" , strerror(err)) ;
return 1;
}
printids( "main thread:" ) ;
sleep ( 1) ;
return 0;
}
|
Modify a program on apue2 and compile it.
Error:
Pthread. c :(. Text + 0x85): Undefined reference to 'pthread _ create'
Because the pthread library is not the default library in Linux, The libpthread. A library is required for connection. Therefore, when using pthread_create to create a thread, add the-lpthread parameter to the compilation:
gcc -o pthread -lpthread pthread.c
This is a column about POSIX thread programming. On the basis of clarifying the concept, the author will detail the POSIX thread library API. This is the first article to show you how to create and cancel a thread.
I. Thread Creation
1.1 threads and processes
A thread is a concept closer to the execution body. It can share data with other threads in the same process, but has its own stack space and independent execution sequence. Threads and processes are introduced on the basis of a serial program to improve program concurrency and program running efficiency and response time.
The use of threads and processes has their own advantages and disadvantages: the thread execution overhead is small, but it is 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 be migrated across machines.
1.2 create thread
POSIX creates a thread through the pthread_create () function. The API definition is as follows:
int pthread_create(pthread_t * thread, pthread_attr_t * attr,
void * (*start_routine)(void *), void * arg)
|
Unlike fork () calling to create a process, the thread created by pthread_create () does not have
Pthread_create () threads) run the same sequence, but run the start_routine (ARG) function. The thread returns the ID of the created thread, and
ATTR is the thread attribute set during thread creation (see below ). The return value of pthread_create () indicates whether the thread is successfully created. Although Arg is void
* Type variable, but it can also be passed to the start_routine () function as any type of parameter. At the same time, start_routine () can return a void
* Type return value, which can also be of another type and is obtained by pthread_join.
1.3 attributes created by threads
The ATTR parameter in pthread_create () is a structure pointer. The elements in the structure correspond to the running attributes of the new thread, including the following items:
_ Detachstate indicates whether the new thread is out of sync with other threads in the process. If it is set to a bit, the new thread cannot use pthread_join () for synchronization and
To release the resources occupied by the row. The default value is pthread_create_joinable. This attribute can also be used after the thread is created and run.
Pthread_detach (). Once it is set to the pthread_create_detach status (whether set at creation or runtime), it cannot be restored.
To the pthread_create_joinable status.
_ Schedpolicy indicates the scheduling policy of the new thread, including sched_other (normal, non-real-time), sched_rr (real-time, rotation method), and
Sched_fifo (real-time, first-in-first-out). The default value is sched_other. The last two scheduling policies are only valid for Super Users. It can be used during runtime
Pthread_setschedparam () to change.
_ Schedparam, a struct
Sched_param structure. Currently, only one sched_priority integer variable represents the thread running priority. This parameter is only used when the scheduling policy is real-time (that is, sched_rr
Or sched_fifo), and can be changed through the pthread_setschedparam () function at runtime. The default value is 0.
_ Inheritsched. Two values are available: pthread_explicit_sched and pthread_inherit_sched,
The former indicates that the new thread explicitly specifies the scheduling policy and scheduling parameters (that is, the value in ATTR), and the latter indicates inheriting the value of the caller thread. Default Value:
Pthread_explicit_sched.
_ Scope indicates the range of CPU competition among threads, that is, the valid range of thread priority. The POSIX standard defines two values:
Pthread_scope_system and pthread_scope_process. The former indicates competition for CPU time with all threads in the system, and the latter indicates that only
The threads in the process compete for the CPU. Currently, linuxthreads only implements the pthread_scope_system value.
There are some values in the pthread_attr_t structure, but pthread_create () is not used.
To set these attributes, POSIX defines a series of attribute setting functions, including pthread_attr_init (), pthread_attr_destroy (), and pthread_attr_get ---/pthread_attr_set --- functions related to each attribute.
1.4 Linux implementation created by threads
We know that the Linux thread implementation is performed outside the kernel, and the kernel provides the do_fork () interface for creating processes (). The kernel provides two system calls: _ clone () and fork.
(), And finally use different parameters to call the do_fork () API in the kernel. Of course, to implement threads, there is no core support for multi-process (actually Lightweight Process) shared data segments, because
Do_fork () provides many parameters, including clone_vm (shared memory space), clone_fs (shared file system information), and clone_files (shared file
File descriptor table), clone_sighand (shared signal handle table), and clone_pid (shared process ID, which is only valid for processes in the kernel, that is, process 0 ). When fork system is used
During the call, the kernel calls do_fork () without any shared attributes, and the process has an independent runtime environment. When pthread_create () is used to create a thread,
These attributes are used to call _ clone (), and all these parameters are passed to the do_fork () in the kernel, so that the created "process" has a shared running environment, only stacks are independent.
_ Clone () is passed in.
A Linux thread exists as a lightweight process in the kernel and has an independent process entry. All creation, synchronization, and deletion operations are performed in the pthread Library outside the kernel.
Pthread
The library uses a management thread (_ pthread_manager (), each process is independent and unique) to manage the creation and termination of threads, allocate thread IDs to threads, and send thread-related signals.
(For example, cancel), while the caller of the main thread (pthread_create () transmits the request information to the management thread through the pipeline.
Ii. Thread Cancellation
2.1 Definition of thread Cancellation
Generally, the thread automatically terminates when the main function exits, but it can also be forcibly terminated by receiving the termination (Cancellation) request from another thread.
2.2 semantics of thread Cancellation
The method for canceling a thread is to send a cancel signal to the target thread, but how to handle the cancel signal is determined by the target thread, or ignore, or terminate immediately, or continue running to cancelation-point, which is determined by different cancelation statuses.
The default processing of the cancel signal received by the thread (that is, the default status of the Creation thread of pthread_create () is to continue running to the cancellation point, that is, to set a canceled status and the thread continues running, it will exit only when it runs to cancelation-point.
2.3 cancellation point
According to 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 functions that will cause blocking
All the calls are cancelation-point, and other pthread functions do not cause cancelation. But the pthread_cancel hand
Because the thread library and C library are not well integrated, the C library function is currently not a cancelation-point; however, the cancel signal will cause thread congestion
And the eintr error code.
Pthread_testcancel () to meet the POSIX standard requirements, that is, the following code segment:
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 execute the inevitable path to the cancellation point, the thread cannot terminate the cancellation request from other external threads. Therefore, you must add pthread_testcancel () to the required path of such a loop body.
2.5 pthread functions related to thread Cancellation
Int pthread_cancel (pthread_t thread)
Send the termination signal to the thread. If the signal is successful, 0 is returned. Otherwise, the value is not 0. Successful sending does not mean that the thread will terminate.
Int pthread_setcancelstate (INT state, int * oldstate)
Sets the response of this thread to the cancel signal. The State has two values: pthread_cancel_enable (default) and
Pthread_cancel_disable, indicating that the signal is set to the cancled status after receiving the signal, and the cancel signal is ignored to continue running; if the old_state is not
Null is saved to the original cancel state for recovery.
Int pthread_setcanceltype (INT type, int * oldtype)
Set the execution time of the canceling action of this thread. The type can be pthread_cancel_deffered or
Pthread_cancel_asychronous, which is valid only when the cancel status is enable. It indicates that after receiving the signal, it continues to run until the next cancel point and then exits.
Execute the cancel action immediately (exit). If the oldtype is not null, it is saved to the canceled action type value of the ship.
Void pthread_testcancel (void)
Check whether the thread is in the canceld status. If yes, cancel the operation. Otherwise, return directly.