Unix、Linux线程安全函数和非线程安全函数

161 篇文章 0 订阅
117 篇文章 0 订阅
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition

2.9 Threads

[THR] [Option Start]The functionality described in this section is dependent on support of the Threads option (and the rest of this section is notfurther shaded for this option). [Option End]

This section defines functionality to support multiple flows of control, called ``threads'', within a process. For thedefinition of threads, see the Base Definitions volume of IEEE Std 1003.1-2001, Section 3.393, Thread.

The specific functional areas covered by threads and their scope include:

  • Thread management: the creation, control, and termination of multiple flows of control in the same process under the assumptionof a common shared address space

  • Synchronization primitives optimized for tightly coupled operation of multiple control flows in a common, shared addressspace

2.9.1 Thread-Safety

All functions defined by this volume of IEEE Std 1003.1-2001 shall be thread-safe, except that the followingfunctions1 need not be thread-safe.


asctime()
basename()
catgets()
crypt()
ctime()
dbm_clearerr()
dbm_close()
dbm_delete()
dbm_error()
dbm_fetch()
dbm_firstkey()
dbm_nextkey()
dbm_open()
dbm_store()
dirname()
dlerror()
drand48()
 


ecvt()
encrypt()
endgrent()
endpwent()
endutxent()
fcvt()
ftw()
gcvt()
getc_unlocked()
getchar_unlocked()
getdate()
getenv()
getgrent()
getgrgid()
getgrnam()
gethostbyaddr()
gethostbyname()
 


gethostent()
getlogin()
getnetbyaddr()
getnetbyname()
getnetent()
getopt()
getprotobyname()
getprotobynumber()
getprotoent()
getpwent()
getpwnam()
getpwuid()
getservbyname()
getservbyport()
getservent()
getutxent()
getutxid()
 


getutxline()
gmtime()
hcreate()
hdestroy()
hsearch()
inet_ntoa()
l64a()
lgamma()
lgammaf()
lgammal()
localeconv()
localtime()
lrand48()
mrand48()
nftw()
nl_langinfo()
ptsname()
 


putc_unlocked()
putchar_unlocked()
putenv()
pututxline()
rand()
readdir()
setenv()
setgrent()
setkey()
setpwent()
setutxent()
strerror()
strtok()
ttyname()
unsetenv()
wcstombs()
wctomb()
 

The ctermid() and tmpnam()functions need not be thread-safe if passed a NULL argument. The wcrtomb() and wcsrtombs() functions need not be thread-safe if passed a NULL psargument.

Implementations shall provide internal synchronization as necessary in order to satisfy this requirement.

2.9.2 Thread IDs

Although implementations may have thread IDs that are unique in a system, applications should only assume that thread IDs areusable and unique within a single process. The effect of calling any of the functions defined in this volume ofIEEE Std 1003.1-2001 and passing as an argument the thread ID of a thread from another process is unspecified. Aconforming implementation is free to reuse a thread ID after the thread terminates if it was created with the detachstateattribute set to PTHREAD_CREATE_DETACHED or if pthread_detach() or pthread_join() has been called for that thread. If a thread is detached, its thread IDis invalid for use as an argument in a call to pthread_detach() or pthread_join().

2.9.3 Thread Mutexes

A thread that has blocked shall not prevent any unblocked thread that is eligible to use the same processing resources fromeventually making forward progress in its execution. Eligibility for processing resources is determined by the schedulingpolicy.

A thread shall become the owner of a mutex, m, when one of the following occurs:

The thread shall remain the owner of m until one of the following occurs:

The implementation shall behave as if at all times there is at most one owner of any mutex.

A thread that becomes the owner of a mutex is said to have ``acquired'' the mutex and the mutex is said to have become``locked''; when a thread gives up ownership of a mutex it is said to have ``released'' the mutex and the mutex is said to havebecome ``unlocked''.

2.9.4 Thread Scheduling

[TPS] [Option Start]The functionality described in this section is dependent on support of the Thread Execution Scheduling option (and the rest of thissection is not further marked for this option). [Option End]

Thread Scheduling Attributes

In support of the scheduling function, threads have attributes which are accessed through the pthread_attr_t threadcreation attributes object.

The contentionscope attribute defines the scheduling contention scope of the thread to be either PTHREAD_SCOPE_PROCESS orPTHREAD_SCOPE_SYSTEM.

The inheritsched attribute specifies whether a newly created thread is to inherit the scheduling attributes of thecreating thread or to have its scheduling values set according to the other scheduling attributes in the pthread_attr_tobject.

The schedpolicy attribute defines the scheduling policy for the thread. The schedparam attribute defines thescheduling parameters for the thread. The interaction of threads having different policies within a process is described as part ofthe definition of those policies.

If the Thread Execution Scheduling option is defined, and the schedpolicy attribute specifies one of the priority-basedpolicies defined under this option, the schedparam attribute contains the scheduling priority of the thread. A conformingimplementation ensures that the priority value in schedparam is in the range associated with the scheduling policy when thethread attributes object is used to create a thread, or when the scheduling attributes of a thread are dynamically modified. Themeaning of the priority value in schedparam is the same as that of priority.

[TSP] [Option Start]If _POSIX_THREAD_SPORADIC_SERVER is defined, the schedparam attribute supports four new members that are used for thesporadic server scheduling policy. These members are sched_ss_low_priority, sched_ss_repl_period,sched_ss_init_budget, and sched_ss_max_repl. The meaning of these attributes is the same as in the definitions thatappear under Process Scheduling. [Option End]

When a process is created, its single thread has a scheduling policy and associated attributes equal to the process' policy andattributes. The default scheduling contention scope value is implementation-defined. The default values of other schedulingattributes are implementation-defined.

Thread Scheduling Contention Scope

The scheduling contention scope of a thread defines the set of threads with which the thread competes for use of the processingresources. The scheduling operation selects at most one thread to execute on each processor at any point in time and the thread'sscheduling attributes (for example, priority), whether under process scheduling contention scope or system schedulingcontention scope, are the parameters used to determine the scheduling decision.

The scheduling contention scope, in the context of scheduling a mixed scope environment, affects threads as follows:

  • A thread created with PTHREAD_SCOPE_SYSTEM scheduling contention scope contends for resources with all other threads in the samescheduling allocation domain relative to their system scheduling attributes. The system scheduling attributes of a thread createdwith PTHREAD_SCOPE_SYSTEM scheduling contention scope are the scheduling attributes with which the thread was created. The systemscheduling attributes of a thread created with PTHREAD_SCOPE_PROCESS scheduling contention scope are the implementation-definedmapping into system attribute space of the scheduling attributes with which the thread was created.

  • Threads created with PTHREAD_SCOPE_PROCESS scheduling contention scope contend directly with other threads within their processthat were created with PTHREAD_SCOPE_PROCESS scheduling contention scope. The contention is resolved based on the threads'scheduling attributes and policies. It is unspecified how such threads are scheduled relative to threads in other processes orthreads with PTHREAD_SCOPE_SYSTEM scheduling contention scope.

  • Conforming implementations shall support the PTHREAD_SCOPE_PROCESS scheduling contention scope, the PTHREAD_SCOPE_SYSTEMscheduling contention scope, or both.

Scheduling Allocation Domain

Implementations shall support scheduling allocation domains containing one or more processors. It should be noted that thepresence of multiple processors does not automatically indicate a scheduling allocation domain size greater than one. Conformingimplementations on multi-processors may map all or any subset of the CPUs to one or multiple scheduling allocation domains, andcould define these scheduling allocation domains on a per-thread, per-process, or per-system basis, depending on the types ofapplications intended to be supported by the implementation. The scheduling allocation domain is independent of schedulingcontention scope, as the scheduling contention scope merely defines the set of threads with which a thread contends for processorresources, while scheduling allocation domain defines the set of processors for which it contends. The semantics of how thiscontention is resolved among threads for processors is determined by the scheduling policies of the threads.

The choice of scheduling allocation domain size and the level of application control over scheduling allocation domains isimplementation-defined. Conforming implementations may change the size of scheduling allocation domains and the binding of threadsto scheduling allocation domains at any time.

For application threads with scheduling allocation domains of size equal to one, the scheduling rules defined for SCHED_FIFO andSCHED_RR shall be used; see Scheduling Policies. All threads with systemscheduling contention scope, regardless of the processes in which they reside, compete for the processor according to theirpriorities. Threads with process scheduling contention scope compete only with other threads with process scheduling contentionscope within their process.

For application threads with scheduling allocation domains of size greater than one, the rules defined for SCHED_FIFO, SCHED_RR,[TSP] [Option Start] and SCHED_SPORADIC [Option End] shall be used in an implementation-definedmanner. Each thread with system scheduling contention scope competes for the processors in its scheduling allocation domain in animplementation-defined manner according to its priority. Threads with process scheduling contention scope are scheduled relative toother threads within the same scheduling contention scope in the process.

[TSP] [Option Start]If _POSIX_THREAD_SPORADIC_SERVER is defined, the rules defined for SCHED_SPORADIC in Scheduling Policies shall be used in an implementation-defined manner forapplication threads whose scheduling allocation domain size is greater than one. [Option End]

Scheduling Documentation

If _POSIX_PRIORITY_SCHEDULING is defined, then any scheduling policies beyond SCHED_OTHER, SCHED_FIFO, SCHED_RR, [TSP] [Option Start]  andSCHED_SPORADIC, [Option End] as well as the effects of the scheduling policiesindicated by these other values, and the attributes required in order to support such a policy, are implementation-defined.Furthermore, the implementation shall document the effect of all processor scheduling allocation domain values supported for thesepolicies.

2.9.5 Thread Cancellation

The thread cancellation mechanism allows a thread to terminate the execution of any other thread in the process in a controlledmanner. The target thread (that is, the one that is being canceled) is allowed to hold cancellation requests pending in a number ofways and to perform application-specific cleanup processing when the notice of cancellation is acted upon.

Cancellation is controlled by the cancellation control functions. Each thread maintains its own cancelability state.Cancellation may only occur at cancellation points or when the thread is asynchronously cancelable.

The thread cancellation mechanism described in this section depends upon programs having set deferred cancelabilitystate, which is specified as the default. Applications shall also carefully follow static lexical scoping rules in their executionbehavior. For example, use of setjmp(), return, goto, and so on, toleave user-defined cancellation scopes without doing the necessary scope pop operation results in undefined behavior.

Use of asynchronous cancelability while holding resources which potentially need to be released may result in resource loss.Similarly, cancellation scopes may only be safely manipulated (pushed and popped) when the thread is in the deferred ordisabled cancelability states.

Cancelability States

The cancelability state of a thread determines the action taken upon receipt of a cancellation request. The thread may controlcancellation in a number of ways.

Each thread maintains its own cancelability state, which may be encoded in two bits:

  1. Cancelability-Enable: When cancelability is PTHREAD_CANCEL_DISABLE (as defined in the Base Definitions volume ofIEEE Std 1003.1-2001, <pthread.h>), cancellation requests againstthe target thread are held pending. By default, cancelability is set to PTHREAD_CANCEL_ENABLE (as defined in <pthread.h>).

  2. Cancelability Type: When cancelability is enabled and the cancelability type is PTHREAD_CANCEL_ASYNCHRONOUS (as defined in <pthread.h>), new or pending cancellation requests may be acted upon at anytime. When cancelability is enabled and the cancelability type is PTHREAD_CANCEL_DEFERRED (as defined in <pthread.h>), cancellation requests are held pending until a cancellation point (seebelow) is reached. If cancelability is disabled, the setting of the cancelability type has no immediate effect as all cancellationrequests are held pending; however, once cancelability is enabled again the new type is in effect. The cancelability type isPTHREAD_CANCEL_DEFERRED in all newly created threads including the thread in which main() was first invoked.

Cancellation Points

Cancellation points shall occur when a thread is executing the following functions:


accept()
aio_suspend()
clock_nanosleep()
close()
connect()
creat()
fcntl()2
fdatasync()
fsync()
getmsg()
getpmsg()
lockf()
mq_receive()
mq_send()
mq_timedreceive()
 


mq_timedsend()
msgrcv()
msgsnd()
msync()
nanosleep()
open()
pause()
poll()
pread()
pselect()
pthread_cond_timedwait()
pthread_cond_wait()
pthread_join()
pthread_testcancel()
putmsg()
 


putpmsg()
pwrite()
read()
readv()
recv()
recvfrom()
recvmsg()
select()
sem_timedwait()
sem_wait()
send()
sendmsg()
sendto()
sigpause()
sigsuspend()
 


sigtimedwait()
sigwait()
sigwaitinfo()
sleep()
system()
tcdrain()
usleep()
wait()
waitid()
waitpid()
write()
writev()
 


A cancellation point may also occur when a thread is executing the following functions:


access()
asctime()
asctime_r()
catclose()
catgets()
catopen()
closedir()
closelog()
ctermid()
ctime()
ctime_r()
dbm_close()
dbm_delete()
dbm_fetch()
dbm_nextkey()
dbm_open()
dbm_store()
dlclose()
dlopen()
endgrent()
endhostent()
endnetent()
endprotoent()
endpwent()
endservent()
endutxent()
fclose()
fcntl()3
fflush()
fgetc()
fgetpos()
fgets()
fgetwc()
fgetws()
fmtmsg()
fopen()
fpathconf()
fprintf()
fputc()
fputs()
fputwc()
fputws()
fread()
freopen()
fscanf()
fseek()
fseeko()
fsetpos()
 


fstat()
ftell()
ftello()
ftw()
fwprintf()
fwrite()
fwscanf()
getaddrinfo()
getc()
getc_unlocked()
getchar()
getchar_unlocked()
getcwd()
getdate()
getgrent()
getgrgid()
getgrgid_r()
getgrnam()
getgrnam_r()
gethostbyaddr()
gethostbyname()
gethostent()
gethostid()
gethostname()
getlogin()
getlogin_r()
getnameinfo()
getnetbyaddr()
getnetbyname()
getnetent()
getopt()4
getprotobyname()
getprotobynumber()
getprotoent()
getpwent()
getpwnam()
getpwnam_r()
getpwuid()
getpwuid_r()
gets()
getservbyname()
getservbyport()
getservent()
getutxent()
getutxid()
getutxline()
getwc()
getwchar()
 


getwd()
glob()
iconv_close()
iconv_open()
ioctl()
link()
localtime()
localtime_r()
lseek()
lstat()
mkstemp()
mktime()
nftw()
opendir()
openlog()
pathconf()
pclose()
perror()
popen()
posix_fadvise()
posix_fallocate()
posix_madvise()
posix_openpt()
posix_spawn()
posix_spawnp()
posix_trace_clear()
posix_trace_close()
posix_trace_create()
posix_trace_create_withlog()
posix_trace_eventtypelist_getnext_id()
posix_trace_eventtypelist_rewind()
posix_trace_flush()
posix_trace_get_attr()
posix_trace_get_filter()
posix_trace_get_status()
posix_trace_getnext_event()
posix_trace_open()
posix_trace_rewind()
posix_trace_set_filter()
posix_trace_shutdown()
posix_trace_timedgetnext_event()
posix_typed_mem_open()
printf()
pthread_rwlock_rdlock()
pthread_rwlock_timedrdlock()
pthread_rwlock_timedwrlock()
pthread_rwlock_wrlock()
putc()
 


putc_unlocked()
putchar()
putchar_unlocked()
puts()
pututxline()
putwc()
putwchar()
readdir()
readdir_r()
remove()
rename()
rewind()
rewinddir()
scanf()
seekdir()
semop()
setgrent()
sethostent()
setnetent()
setprotoent()
setpwent()
setservent()
setutxent()
stat()
strerror()
strerror_r()
strftime()
symlink()
sync()
syslog()
tmpfile()
tmpnam()
ttyname()
ttyname_r()
tzset()
ungetc()
ungetwc()
unlink()
vfprintf()
vfwprintf()
vprintf()
vwprintf()
wcsftime()
wordexp()
wprintf()
wscanf()
 

An implementation shall not introduce cancellation points into any other functions specified in this volume ofIEEE Std 1003.1-2001.

The side effects of acting upon a cancellation request while suspended during a call of a function are the same as the sideeffects that may be seen in a single-threaded program when a call to a function is interrupted by a signal and the given functionreturns [EINTR]. Any such side effects occur before any cancellation cleanup handlers are called.

Whenever a thread has cancelability enabled and a cancellation request has been made with that thread as the target, and thethread then calls any function that is a cancellation point (such as pthread_testcancel() or read()), thecancellation request shall be acted upon before the function returns. If a thread has cancelability enabled and a cancellationrequest is made with the thread as a target while the thread is suspended at a cancellation point, the thread shall be awakened andthe cancellation request shall be acted upon. However, if the thread is suspended at a cancellation point and the event for whichit is waiting occurs before the cancellation request is acted upon, it is unspecified whether the cancellation request is actedupon or whether the cancellation request remains pending and the thread resumes normal execution.

Thread Cancellation Cleanup Handlers

Each thread maintains a list of cancellation cleanup handlers. The programmer uses the pthread_cleanup_push() and pthread_cleanup_pop() functions to place routines on and remove routines fromthis list.

When a cancellation request is acted upon, or when a thread calls pthread_exit(), the thread first disables cancellation by setting its cancelabilitystate to PTHREAD_CANCEL_DISABLE and its cancelability type to PTHREAD_CANCEL_DEFERRED. The cancelability state shall remain set toPTHREAD_CANCEL_DISABLE until the thread has terminated. The behavior is undefined if a cancellation cleanup handler orthread-specific data destructor routine changes the cancelability state to PTHREAD_CANCEL_ENABLE.

The routines in the thread's list of cancellation cleanup handlers are invoked one by one in LIFO sequence; that is, the lastroutine pushed onto the list (Last In) is the first to be invoked (First Out). When the cancellation cleanup handler for a scope isinvoked, the storage for that scope remains valid. If the last cancellation cleanup handler returns, thread-specific datadestructors (if any) associated with thread-specific data keys for which the thread has non-NULL values will be run, in unspecifiedorder, as described for pthread_key_create().

After all cancellation cleanup handlers and thread-specific data destructors have returned, thread execution is terminated. Ifthe thread has terminated because of a call to pthread_exit(), thevalue_ptr argument is made available to any threads joining with the target. If the thread has terminated by acting on acancellation request, a status of PTHREAD_CANCELED is made available to any threads joining with the target. The symbolic constantPTHREAD_CANCELED expands to a constant expression of type ( void *) whose value matches no pointer to an object in memorynor the value NULL.

A side effect of acting upon a cancellation request while in a condition variable wait is that the mutex is re-acquired beforecalling the first cancellation cleanup handler. In addition, the thread is no longer considered to be waiting for the condition andthe thread shall not have consumed any pending condition signals on the condition.

A cancellation cleanup handler cannot exit via longjmp() or siglongjmp().

Async-Cancel Safety

The pthread_cancel(), pthread_setcancelstate(), and pthread_setcanceltype() functions are defined to be async-cancel safe.

No other functions in this volume of IEEE Std 1003.1-2001 are required to be async-cancel-safe.

2.9.6 Thread Read-Write Locks

Multiple readers, single writer (read-write) locks allow many threads to have simultaneous read-only access to data whileallowing only one thread to have exclusive write access at any given time. They are typically used to protect data that is readmore frequently than it is changed.

One or more readers acquire read access to the resource by performing a read lock operation on the associated read-write lock. Awriter acquires exclusive write access by performing a write lock operation. Basically, all readers exclude any writers and awriter excludes all readers and any other writers.

A thread that has blocked on a read-write lock (for example, has not yet returned from a pthread_rwlock_rdlock() or pthread_rwlock_wrlock() call) shall not prevent any unblocked thread that iseligible to use the same processing resources from eventually making forward progress in its execution. Eligibility for processingresources shall be determined by the scheduling policy.

Read-write locks can be used to synchronize threads in the current process and other processes if they are allocated in memorythat is writable and shared among the cooperating processes and have been initialized for this behavior.

2.9.7 Thread Interactions with Regular File Operations

All of the functions chmod(), close(),fchmod(), fcntl(), fstat(), ftruncate(), lseek(), open(), read(), readlink(), stat(), symlink(), and write() shall be atomic with respect to each other in the effects specified inIEEE Std 1003.1-2001 when they operate on regular files. If two threads each call one of these functions, each call shalleither see all of the specified effects of the other call, or none of them.

2.9.8 Use of Application-Managed Thread Stacks

An ``application-managed thread stack'' is a region of memory allocated by the application-for example, memory returned by themalloc() or mmap() functions-anddesignated as a stack through the act of passing an address related to that memory as the stackaddr argument to pthread_attr_setstackaddr() (obsolete) or by passing the address and sizeof the stack, respectively, as the stackaddr and stacksize arguments to pthread_attr_setstack(). Application-managed stacks allow the application toprecisely control the placement and size of a stack.

The application grants to the implementation permanent ownership of and control over the application-managed stack when theattributes object in which the stack or stackaddr attribute has been set is used, either by presenting thatattribute's object as the attr argument in a call to pthread_create()that completes successfully, or by storing a pointer to the attributes object in the sigev_notify_attributes member of astruct sigevent and passing that struct sigevent to a function accepting such argument that completes successfully.The application may thereafter utilize the memory within the stack only within the normal context of stack usage within or properlysynchronized with a thread that has been scheduled by the implementation with stack pointer value(s) that are within the range ofthat stack. In particular, the region of memory cannot be freed, nor can it be later specified as the stack for another thread.

When specifying an attributes object with an application-managed stack through the sigev_notify_attributes member of astruct sigevent, the results are undefined if the requested signal is generated multiple times (as for a repeatingtimer).

Until an attributes object in which the stack or stackaddr attribute has been set is used, the application retainsownership of and control over the memory allocated to the stack. It may free or reuse the memory as long as it either deletes theattributes object, or before using the attributes object replaces the stack by making an additional call to the same function,either pthread_attr_setstackaddr() or pthread_attr_setstack(), that was used originally to designate the stack.There is no mechanism to retract the reference to an application-managed stack by an existing attributes object.

Once an attributes object with an application-managed stack has been used, that attributes object cannot be used again by asubsequent call to pthread_create() or any function accepting a structsigevent with sigev_notify_attributes containing a pointer to the attributes object, without designating an unusedapplication-managed stack by making an additional call to the function originally used to define the stack, pthread_attr_setstack() or pthread_attr_setstackaddr().


Footnotes
1.
The functions in the table are not shaded to denote applicable options. Individual reference pages should be consulted.
2.
When the cmd argument is F_SETLKW.
4.
For any value of the cmd argument.
4.
If opterr is non-zero.

UNIX ® is a registered Trademark of The Open Group.
POSIX ® is a registered Trademark of The IEEE.
[ Main Index | XBD | XCU | XSH | XRAT]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值