zoukankan      html  css  js  c++  java
  • [译] man 7 pthreads

    NAME
         pthreads - POSIX threads
     
    DESCRIPTION
         POSIX.1 指定了一组叫做POSIX线程或Pthreads的编程接口(函数,头文件)。单个进程可以包含多个线程,所有线程执行相同的程序。这些线程共享相同的全局存储空间(数据段和堆),但每个线程有其自己的栈(自动变量)。
     
         POSIX.1 也要求共享一些其它属性(例如,进程范围内而不是每个线程的属性)
    • 进程ID
    • 父进程ID
    • 进程组ID和会话ID
    • 控制终端
    • 用户和组IDs
    • 打开的文件描述符
    • 记录锁(参考fcntl(2))
    • 信号处理
    • 文件创建掩码模式(umask(2))
    • 当前目录(chdir(2))和root目录(chroot(2))
    • 定时器(settimer(2))和POSIX定时器(timer_create(2))
    • 优先级值(setpriority(2))
    • 资源限制(setrlimit(2))
    • CPU使用时间(times(2))和资源使用情况的测量值
     
         和栈一样,POSIX.1指出,对于各个线程其它各属性是不同的,包括:
    • 线程ID(pthread_t数据类型)
    • 信号掩码(pthread_sigmask(3))
    • errno变量
    • 替换信号处理栈
    • 实时调度策略和优先级(shed_setscheduler(2)和sched_setparam(2))
     
         下面是只是Linux系统的特点,对于每个线程都不同:
    • capabilities(capabilities(7))
    • CPU affinity(sched_setaffinity(2))
         线程函数返回值
         大多数线程函数成功后返回0,失败后返回错误码。注意线程函数不会设置errno值,对每个能返回错误码的线程函数,POSIX.1指定这种函数对于错误EINTR永远也不会失败。
     
         线程ID
         在一个进程中每个线程都有唯一一个线程ID(保存在pthread_t类型中),这个ID通过调用pthread_create(3)得到,一个线程可以通过pthread_self()得到其自身线程ID,线程ID仅在进程范围内是唯一的,一个线程ID还能被重新利用,例如,在一个终止线程在被回收后,或者一个分离的线程终止后,这个线程ID可能被新的线程使用。在所有接收线程ID作为参数的线程函数中,这个ID实际指向相同调用进程中的线程。
     
         线程安全函数
         一个线程安全函数可以同时被多个线程安全地调用(例如,不管是什么都能给出相同的结果)。
         POSIX.1-2001  和 POSIX.1-2008 要求所有在标准中指定的函数是线程安全的,除了下面的函数
               asctime()                                                    
               basename()                                                   
               catgets()                                                    
               crypt()                                                      
               ctermid() if passed a non-NULL argument                      
               ctime()                                                      
               dbm_clearerr()                                               
               dbm_close()                                                  
               dbm_delete()                                                 
               dbm_error()                                                  
               dbm_fetch()                                                  
               dbm_firstkey()                                               
               dbm_nextkey()                                                
               dbm_open()                                                   
               dbm_store()                                                  
               dirname()                                                    
               dlerror()                                                    
               drand48()                                                    
               ecvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)]
               encrypt()                                                    
               endgrent()                                                   
               endpwent()                                                   
               endutxent()                                                  
               fcvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)]
               ftw()                                                        
               gcvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)]
               getc_unlocked()                                              
               getchar_unlocked()                                           
               getdate()                                                    
               getenv()                                                            
               getgrent()                                                          
               getgrgid()                                                          
               getgrnam()                                                          
               gethostbyaddr() [POSIX.1-2001 only (function removed in POSIX.1-2008)]
               gethostbyname() [POSIX.1-2001 only (function removed in POSIX.1-2008)]
               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()                              
               strsignal() [Added in POSIX.1-2008]     
               strtok()                                
               system() [Added in POSIX.1-2008]        
               tmpnam() if passed a non-NULL argument  
               ttyname()                               
               unsetenv()                              
               wcrtomb() if its final argument is NULL 
               wcsrtombs() if its final argument is NULL
               wcstombs()                              
               wctomb()                                 
     
         异步撤销安全函数
         一个异步撤销安全函数是当异步撤销能力被启用后,在应用中可以被安全地调用。
         仅仅下面的函数在POSIX.1-2001和POSIX.1-2008要求是异步线程安全的:
               pthread_cancel()       
               pthread_setcancelstate()
               pthread_setcanceltype()
     
         撤销点
         POSIX.1 指定一些确定的函数必须是撤销点,而还有一些函数可能是撤销点。如果一个线程是可以撤销的,它的撤销类型是延迟的,一个撤销请求对那个线程还是未决的,然后当它调用一个撤销点时线程被撤销。
         下面的函数POSIX.1-2001和/或POSIX.1-2008要求是撤销点:
               accept()
               aio_suspend()
               clock_nanosleep()
               close()
               connect()
               creat()
               fcntl() F_SETLKW
               fdatasync()
               fsync()
               getmsg()
               getpmsg()
               lockf() F_LOCK
               mq_receive()
               mq_send()
               mq_timedreceive()
               mq_timedsend()
               msgrcv()
               msgsnd()
               msync()
               nanosleep()
               open()
               openat() [Added in POSIX.1-2008]
               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() [POSIX.1-2001 only (moves to "may" list in POSIX.1-2008)]
               sigsuspend()
               sigtimedwait()
               sigwait()
               sigwaitinfo()
               sleep()
               system()
               tcdrain()
               usleep() [POSIX.1-2001 only (function removed in POSIX.1-2008)]
               wait()
               waitid()
               waitpid()
               write()
               writev()
     
         下面的函数根据POSIX.1-2001和/或POSIX.1-2008或许可能是撤销点:
               access()
               asctime()
               asctime_r()
               catclose()
               catgets()
               catopen()
               chmod() [Added in POSIX.1-2008]
               chown() [Added in POSIX.1-2008]
               closedir()
               closelog()
               ctermid()
               ctime()
               ctime_r()
               dbm_close()
               dbm_delete()
               dbm_fetch()
               dbm_nextkey()
               dbm_open()
               dbm_store()
               dlclose()
               dlopen()
               dprintf() [Added in POSIX.1-2008]
               endgrent()
               endhostent()
               endnetent()
               endprotoent()
               endpwent()
               endservent()
               endutxent()
               faccessat() [Added in POSIX.1-2008]
               fchmod() [Added in POSIX.1-2008]
               fchmodat() [Added in POSIX.1-2008]
               fchown() [Added in POSIX.1-2008]
               fchownat() [Added in POSIX.1-2008]
               fclose()
               fcntl() (for any value of cmd argument)
               fflush()
               fgetc()
               fgetpos()
               fgets()
               fgetwc()
               fgetws()
               fmtmsg()
               fopen()
               fpathconf()
               fprintf()
               fputc()
               fputs()
               fputwc()
               fputws()
               fread()
               freopen()
               fscanf()
               fseek()
               fseeko()
               fsetpos()
               fstat()
               fstatat() [Added in POSIX.1-2008]
               ftell()
               ftello()
               ftw()
               futimens() [Added in POSIX.1-2008]
               fwprintf()
               fwrite()
               fwscanf()
               getaddrinfo()
               getc()
               getc_unlocked()
               getchar()
               getchar_unlocked()
               getcwd()
               getdate()
               getdelim() [Added in POSIX.1-2008]
               getgrent()
               getgrgid()
               getgrgid_r()
               getgrnam()
               getgrnam_r()
               gethostbyaddr() [SUSv3 only (function removed in POSIX.1-2008)]
               gethostbyname() [SUSv3 only (function removed in POSIX.1-2008)]
               gethostent()
               gethostid()
               gethostname()
               getline() [Added in POSIX.1-2008]
               getlogin()
               getlogin_r()
               getnameinfo()
               getnetbyaddr()
               getnetbyname()
               getnetent()
               getopt() (if opterr is nonzero)
               getprotobyname()
               getprotobynumber()
               getprotoent()
               getpwent()
               getpwnam()
               getpwnam_r()
               getpwuid()
               getpwuid_r()
               gets()
               getservbyname()
               getservbyport()
               getservent()
               getutxent()
               getutxid()
               getutxline()
               getwc()
               getwchar()
               getwd() [SUSv3 only (function removed in POSIX.1-2008)]
               glob()
               iconv_close()
               iconv_open()
               ioctl()
               link()
               linkat() [Added in POSIX.1-2008]
               lio_listio() [Added in POSIX.1-2008]
               localtime()
               localtime_r()
               lockf() [Added in POSIX.1-2008]
               lseek()
               lstat()
               mkdir() [Added in POSIX.1-2008]
               mkdirat() [Added in POSIX.1-2008]
               mkdtemp() [Added in POSIX.1-2008]
               mkfifo() [Added in POSIX.1-2008]
               mkfifoat() [Added in POSIX.1-2008]
               mknod() [Added in POSIX.1-2008]
               mknodat() [Added in POSIX.1-2008]
               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()
               psiginfo() [Added in POSIX.1-2008]
               psignal() [Added in POSIX.1-2008]
               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()
               readlink() [Added in POSIX.1-2008]
               readlinkat() [Added in POSIX.1-2008]
               remove()
               rename()
               renameat() [Added in POSIX.1-2008]
               rewind()
               rewinddir()
               scandir() [Added in POSIX.1-2008]
               scanf()
               seekdir()
               semop()
               setgrent()
               sethostent()
               setnetent()
               setprotoent()
               setpwent()
               setservent()
               setutxent()
               sigpause() [Added in POSIX.1-2008]
               stat()
               strerror()
               strerror_r()
               strftime()
               symlink()
               symlinkat() [Added in POSIX.1-2008]
               sync()
               syslog()
               tmpfile()
               tmpnam()
               ttyname()
               ttyname_r()
               tzset()
               ungetc()
               ungetwc()
               unlink()
               unlinkat() [Added in POSIX.1-2008]
               utime() [Added in POSIX.1-2008]
               utimensat() [Added in POSIX.1-2008]
               utimes() [Added in POSIX.1-2008]
               vdprintf() [Added in POSIX.1-2008]
               vfprintf()
               vfwprintf()
               vprintf()
               vwprintf()
               wcsftime()
               wordexp()
               wprintf()
               wscanf()
     
         具体实现或许会标记其它非标准指定的撤销函数,特别地,具体实现可能会标记出其它任何阻塞的非标准函数作为撤销点。(这包括大多数可能生成文件的函数)
     
         在Linux上编译多线程程序
         在Linux上,程序使用了Phtreads API应该使用 cc -pthread来编译。
     
         POSIX线程的Linux实现
         随着时间的推移,在GNU C库中提供两种线程的实现
    • LinuxThreads: 这是原始的Pthreads实现,从glibc 2.4以后,这种实现不再被支持。
    • NPTL: (Native POSIX Threads Library)这种实现比较新,与LinuxThreds相比,NPTL提供了与POSIX.1规范更近的一致性,当创建大量线程时也有更好的性能,NPTL从glibc 2.3.2以后都是可用的,并且需要在Linux 2.6 内核中提供的特性。
         这两种实现被称之为1:1实现,意思是每个线程映射到内核调度实体,两种实现都是通过Linux clone(2)系统调用来实现,在NPTL,线程同步原语(mutexes,线程终止等待)使用futex(2)系统调用实现。
     
         LinuxThreads
         这种实现值得注意的特性如下:
    • 除了主(初始)线程,使用pthread_create(3)创建的线程,在实现中创建了一个“管理者”线程。这个线程处理线程创建和终止。(如果这个线程被不经意地杀死后,可能会导致问题出现)
    • 在实现的内部使用了信号。在Linux 2.2以后,使用了前三个实时信号,在更旧的Linux内核中,SIGUSR1和SIGUSR2被使用,应用程序要避免使用被线程实现使用的信号。
    • 线程不共享进程IDs。(实际上,LinuxThreads线程实现为比常用进程共享更多信息的进程,但是不共享通用进程ID。)LinuxThreads(包括管理线程)在使用ps(1)是都能作为分离的进程被看到。
     
         LinuxThreads实现在很多方面偏离了POSIX.1规范,包括如下:
    • 调用getpid(2)返回每个线程的不同值。
    • 在线程中而不是主线程中调用getppid(2)返回管理线程的进程ID;在这些线程中getppid(2)的返回值应该返回与主线程中getppid(2)相同的值。
    • 当一个线程使用fork(2)创建一个子进程时,任何线程应该能能够在其子进程上wait(2)。然而,实现仅仅允许创建了子进程的那个线程执行wait(2)。
    • 当一个线程调用execve(2),所有其它线程被终止(POSIX.1要求)。然而,最终的进程使用了与与调用execve(2)线程相同的PID,应该是与主线有相同的PID。
    • 线程不共享用户和组IDs,如果应用通过使用seteuid(2)或其它类似函数改变了其相关内容,这就会对设置用户ID程序造成问题,在线程函数中会导致失败。
    • 线程不共享公用的会话ID和进程组ID。
    • 线程不共享使用fcntl(2)创建的记录锁。
    • times(2)和getrusage(2)返回的信息是每个线程级别的而不是进程级别的。
    • 线程不共享信号量撤销值(参考semop(2))。
    • 线程不共享间隔定时器。
    • 线程不共享公用优先级值。
    • POSIX.1 区分指向整个进程的信号和单个线程的信号。根据POSIX.1,一个指向进程的信号(使用kill发送)应该被进程中单个选定的线程来处理。LinuxThreads不支持指向进程进程的信号:信号只能发送给特定的线程。
    • 线程有不同的替换信号栈设置,一个新的线程的替换信号栈设置从创建了线程的线程中拷贝而来,所以线程初始时是共享替换信号栈的。(一个新的线程应该使用未定义的替换信号栈启动,如果两个线程在同一时刻处理信号使用共享的替换信号栈,不可预测的程序失败可能出现)。
         NPTL
         使用NPTL,在进程中的所有线程放在相同的线程组中;线程组中的所有成员共享相同的PID,NPTL不使用管理者线程,NPTL在内部使用前两个实时信号(参看signal(7));这些信号不能被应用程序使用。
         NPTL至少还与POSIX.1有下面的不一致:
    • 线程不共享公用的优先级值
     
         一些其它的NPTL不一致仅仅出现在老版本内核中:
    • 使用times(2)和getrusage(2)返回的信息是线程级的而不是进程范围内的(在内核2.6.9中修复)。
    • 线程不共享资源限制(在内核2.6.10中修复)。
    • 线程不共享间隔定时器(在内核2.6.12中修复)。
    • 仅仅主线程被允许使用setsid(2)来开启一个新的会话(在内核2.6.16中修复)。
    • 仅仅主线程被允许使用setpgid(2)使得一个进程成为进程组leader(在内核2.6.16中修复)。
    • 线程拥有不同的替换信号栈设置,然而,一个新线程的替换信号栈设定是从创建它的线程中拷贝而来,所以初始时共享替换信号处理栈(在内核2.6.16中修复)。
     
         注意下面的更多关于NPTL实现:
    • 如果栈大小软资源限制(查看setrlimit(2)中RLIMIT_STACK中的描述)被设置成除了unlimited之外的值,这个值定义了新线程的默认栈大小。为了生效,这个限制必须在程序运行前设置,也许可以使用ulimit -s这个shell内置的命令。
         确定线程实现
         从glibc 2.3.2以后,getconf(1)命令能被用来确定系统的线程实现,例如
         
              bash$ getconf GNU_LIBPTHREAD_VERSION
              NPTL 2.3.4
         
         其它glibc版本,一个下面的命令可以用了确定默认线程实现:
     
               bash$ $( ldd /bin/ls | grep libc.so | awk '{print $3}' ) |
                               egrep -i 'threads|nptl'
                       Native POSIX Threads Library by Ulrich Drepper et al
     
         选择线程实现: LD_ASSUME_KERNEL
         在支持LinuxThreads和NPTL(例如,glibc 2.3.x)的系统上,LD_ASSUME_KERNEL环境变量可以被用来重写动态链接器的线程实现的默认选项,这个变量指示动态链接器用来给出其运行在特殊内核版本之上。通过指定不支持NPTL的内核版本,可以强制使用LinuxThreads。(这样做常见的原因就是就是为了运行依赖于在LinuxThreads中一些不一致的特性(不工作)应用。)例如:
     
    SEE ALSO
           clone(2), futex(2), gettid(2), proc(5), futex(7), sigevent(7), signal(7), and various Pthreads manual pages, for example: pthread_attr_init(3), pthread_atfork(3), pthread_cancel(3), pthread_cleanup_push(3), pthread_cond_signal(3), pthread_cond_wait(3), pthread_create(3), pthread_detach(3), pthread_equal(3), pthread_exit(3), pthread_key_create(3), pthread_kill(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), pthread_once(3), pthread_setcancelstate(3), pthread_setcanceltype(3), pthread_setspecific(3), pthread_sigmask(3), pthread_sigqueue(3), and pthread_testcancel(3)
     
    COLOPHON
           This page is part of release 3.35 of the Linux man-pages project.  A description of the project, and information about reporting bugs, can be found at http://man7.org/linux/man-pages/.
  • 相关阅读:
    创建SSIS包—ETL中典型的数据清洗
    SSIS中的容器和数据流—数据转换(Transformations)
    创建SSIS包—循环和动态package
    SSIS中的容器和数据流—数据转换(Transformations)续
    创建SSIS包—建立端到端的package
    SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务
    SSIS中的容器和数据流—调试工具数据视图
    SQL点滴11—重置win7登录密码影响SQL登录
    SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比
    SSIS中的容器和数据流—举例说明数据转换任务
  • 原文地址:https://www.cnblogs.com/wangshide/p/3165084.html
Copyright © 2011-2022 走看看