《Linux/UNIX系统编程手册》 英文版读书笔记第29章

errnois defined as amacro that expands into afunction call returning a modifiable lvalue that is distinct for each thread. (Sincethe lvalue is modifiable, it is still possible to write assignment statements of theformerrno = valuein threaded programs.)

On Linux, programs that use the Pthreads API must be compiled with thecc –pthreadoption. The effects of this option include the following:The_REENTRANTpreprocessor macro is defined. This causes the declarations of afew reentrant functions to be exposed.z The program is linked with the libpthread library (the equivalent of–lpthread).

When a program is started, the resulting process consists of a single thread, calledthe initial or mainthread

#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg);

The thread that callspthread_create()continuesexecution with the next statement that follows the callTypically,argpoints to a global or heap variable, but it can also be specified asNULLPTHREAD_CANCELED, the value returnedwhen a thread is canceled (see Chapter 32), is usually some implementationdefined integer value cast tovoid *。A portable application would need to ensure that normallyterminating threads don’t return integer values that match PTHREAD_CANCELED onany of the implementations on which the application is to runSUSv3 explicitly notes that the implementation need not initialize the bufferpointed to bythreadbeforethe new thread starts executing; that is, the new threadmay start running beforepthread_create()returns to its caller.If the newthread needs to obtain its own ID, then it must do so usingpthread_self()线程的终止有四种方式:z The thread’s start function performs a return specifying a return value for thethread.z The thread calls pthread_exit() (described below).z The thread is canceled using pthread_cancel() (described in div 32.1).z Any of the threads calls exit(), or themain thread performs areturn(in themain()function), which causes all threads in the process to terminate immediately.

include <pthread.h>void pthread_exit(void *retval);

pthread_exit()can be called from any function that hasbeen called by the thread’sstart function.pthread_exitspecifies a returnvalue that can be obtained in another thread by callingpthread_joinThe value pointedto by retval should not be located on the thread’s stack, since the contents of thatstack becomeundefinedon thread termination。The same statement applies to the value given to areturnstatement inthe thread’s start function.If the main thread callspthread_exit()instead of callingexit()or performing areturn, then the other threadscontinue to execute获取线程ID

include <pthread.h>pthread_t pthread_self(void);

检测线程ID是否一样

include <pthread.h>int pthread_equal(pthread_t t1, pthread_t t2);

SUSv3 also notes that an implementation is permitted toreusea thread ID after aterminatedthread has been joined withpthread_join()orafter adetachedthread has terminatedPOSIX thread IDs are assigned and maintained bythe threading implementationThe thread ID returned bygettid()is a number(similar to a process ID) that is assigned by thekernelpthread_join() 函数等待指定的线程thread终止,thread终止后pthread_join立即返回

include <pthread.h>int pthread_join(pthread_t thread, void **retval);Returns 0 on success, or a positive error number on error

Calling pthread_join() for a thread ID that has been previously joined can leadto unpredictable behavior重复对同一个thread调用两次pthread_join会造成无法预测的行为,it might instead join with a thread createdlater that happened to reuse the same thread ID可能join一个thread,是在之后创建的,只不过重用了之前的thread ID.If a thread is not detached (see div 29.7), then we must join with it usingpthread_join(). If we fail to do this, then, when the thread terminates, it producesthe thread equivalent of a zombie process如果线程没有被detach,我们必用对它使用pthread_join,否则该线程终止后变为僵尸线程。The task that pthread_join()performs for threads is similar to that performedbywaitpid()for processes. However, there are some notable differencespthread_join和waitpid两个函数很相似,但是也有一些显著的不同。Threads are peers. Any thread in a process can usepthread_join()to join withany other thread in the process. For example, if thread A creates thread B,which creates thread C, then it is possible for thread A to join with thread C, orvice versa. This differs from the hierarchical relationship between processes.When a parent process creates a child usingfork(), it is the only process thatcanwait()on that child. There is no such relationship between the thread thatcallspthread_create()and the resulting new thread.线程是平等的,比如线程A创建了线程B,线程B创建了线程C,那么线程A可以join线程C,反之也可以。在进程中,只有父进程通过fork创建了子进程,只有这个父进程可以wait这个子进程。z There is no way of saying “join with any thread” (for processes, we can do thisusing the callwaitpid(–1, &status, options)); nor is there a way to do a nonblockingjoin (analogous to thewaitpid()WNOHANGflag). There are ways to achieve similarfunctionality using condition variables;线程不像进程,进程wait可以等待任意进程终止,线程也没有nonblocking 等待,不过线程可以通过使用条件值来实现相同功能。The limitation that pthread_join() can join only with a specific thread ID isintentional. The idea is that a program should join only with the threads that it“knows” about.pthread_join的缺点就是只能join特定的threadID.这样设计的其中的原因就是一个程序只能Join它知道的线程。The problem with a “join with any thread” operation stems fromthe fact that there is no hierarchy of threads, so such an operation could indeedjoin withanythread, including one that was privately created by a library function.(The condition-variable technique that we show in div30.2.4allows athread to join only with any other thread that it knows about.) As a consequence, the library would no longer be able to join with that thread in order toobtain its status, and it would erroneously try to join with a thread ID that hadalready been joined. In other words, a “join with any thread” operation isincompatible with modular program design.下载地址见:http://blog.csdn.net/wdy_yx/article/details/41323387一个背包,几本书,所有喜欢的歌,

《Linux/UNIX系统编程手册》 英文版读书笔记第29章

相关文章:

你感兴趣的文章:

标签云: