相关函数列表
//线程属性,pthread_attr_t结构体保护的就是操作系统实现支持的所有线程属性 //下面所有函数都是是成功返回0,否则返回错误编号 #include <pthread.h> int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr); //如果对某个线程终止状态不感兴趣,可以使用pthread_detach函数让系统在 //线程退出时收回所占用的资源 //可以detachstate为以下两个值 //1.PTHREAD_CREATE_DETACHED 分离状态启动线程 //2.PTHREAD_CREATE_JOINABLE 正常启动线程 #include <pthread.h> int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); int pthread_attr_setdetachstate(pthread_attr_t *attr, in *detachstate); //对线程栈属性进行管理 #include <pthread.h> int pthread_attr_getstack(const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize); int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); //通过下面函数设置stacksize #include <pthread.h> int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize); int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); //线程属性guardsize控制线程栈末尾以后用以避免溢出的口占内存的大小,这个 //属性默认值是由具体实现来定义,但常用值是系统页大小,可以把其设置为0, //不允许属性的这种特征行为发生,在这种情况下,不会提供警戒缓冲区。同样, //如果修改了线程属性stackaddr,系统就认为我们将自己管理栈,警戒缓冲区 //机制无效 #include <pthread.h> int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize); int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); //互斥量属性,互斥量的返回值都是成功返回0,否则返回错误编号 #include <pthread.h> int pthread_mutexattr_init(pthread_muexattr_t *attr); int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); //修改进程共享属性 #include <pthread.h> int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared); int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); //修改和获取健壮的互斥量属性 #include <ptherad.h> int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict attr, int *restrict robust); int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust); //线程可以调用下面函数,指明与该互斥量相关的状态在互斥量解锁之前是一致的 #include <pthread.h> int pthread_mutex_consistent(pthread_mutex_t *mutex); //修改和获取互斥量属性 #include <pthread.h> int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restirct type); int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); //读写锁属性,读写锁的返回值都是成功返回0,否则返回错误编号 #include <pthread.h> int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); int phtread_rwlockattr_destroy(pthread_rwlockattr_t *attr); //和互斥量一样,读写锁也有一对函数用于读取和设置进程共享属性 #include <pthraed.h> int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared); int pthraed_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared); //条件变量属性 #include <pthrad.h> int pthread_condattr_init(pthread_condattr_t *attr); int pthread_condattr_destroy(pthread_condattr_t *attr); //条件变量也支持进程共享属性,可以被单个进程的多个线程使用 //条件变量的返回值都是成功返回0,否则返回错误编号 #include <pthread.h> int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); //条件变量可以设置时钟属性 #include <pthread.h> int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id); int pthread_condattr_setclock(pthread_condattr_t *atr, clockid_t clock_id); //屏障属性(屏障的返回值都是成功返回0,否则返回错误编号) #include <pthread.h> int pthread_barrierattr_init(pthread_barrierattr_t *attr); int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); //屏障的进程共享属性 int pthraed_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared); int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); //POSIX.1提供了安全方式管理FILE对象的方法,可以使用下面方式获取给定FILE对象关联的锁,这个 //锁是递归的,当占有这把锁后可以再次获取该锁,不会导致死锁。虽然这种锁的具体实现并无规定, //但要求所有操作FILE对象的标准I/O例程的动作行为必须看起来就像他们内部调用了flockfile和 //funlockfile,以下函数都是成功返回0,否则返回错误编号 #include <stdio.h> int ftrylockfile(FILE *fp); void flockfile(FILE *fp); void funlockfile(FILE *fp); //如果标准I/O例程都获取他们各自的锁,那么在做一次一个字符的I/O时就会出现严重的性能下降,在 //这种情况下,需要对每一个字符的读写操作都进行获取锁和释放锁的动作。为了避免这种开销,出现 //了不加锁版本的基于字符的标准I/O例程 #include <stdio.h> int getchar_unlocked(void); int getc_unlocked(FILE *fp); //这两个函数若成功返回下一个字符,若遇到文件尾或出错返回EOF int putchar_unlocked(int c); int putc_unlocked(int c, FILE *fp); //线程特定数据(thread0specific data),也成为线程私有数据(thread-private data),是存储和存储 //某个特定线程相关数据的一种机制,每个线程都有自己单独的数据副本,而不需要担心与其他线程的 //同步访问问题 #include <pthread.h> int phtread_key_create(pthread_key_t *keyp, void (*destructor)(void*)); //取消与现场特定数据值之间关联关系 #include <pthread.h> int pthread_key_delete(pthread_key_t key); //解决竞争条件 #inlude <pthread.h> pthread_once_t initflag = PHTREAD_ONCE_INIT; int pthread_once(pthread_once_t *initflag, void (*initfn)(void)); //通过下面函数设置和获取线程特定数据的地址 #include <pthread.h> void *pthread_getspecific(pthread_key_t key); int pthread_setspecific(pthread_key_t key, const void *value); //线程取消,取消状态可以是PTHREAD_CANCEL_ENABLE或者PTHREAD_CANCEL_DISABLE #include <pthread.h> int pthread_setcancelstate(int state, int *oldstate); //添加自己的取消点 #include <pthread.h> void pthread_testcancel(void); //修改取消类型,参数type可以使PTHREAD_CANCEL_DEFERRED,或者PTHREAD_CANCEL_ASYNCHRONOUS #include <pthread.h> int pthread_setcanceltype(int type,int *oldtype); //线程和信号 #include <signal.h> int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); //等待一个或多个信号出现 #include <signal.h> int sigwait(const sigset_t *restirct set, int *restrict signop); //要把信号发给进程可以调用kill,要把信号发给线程可以调用pthread_kill #include <signal.h> int pthread_kill(pthread_t thread, int signo); //线程和fork,最多可以安装3个帮助清理锁的函数 //prepare fork处理程序由父进程在fork创建子进程前调用,这个fork处理程序的任务是获取父进程 // 定义的所有锁 //parent fork处理程序是在fork创建子进程以后,返回之前在父进程上下文中调用的。这个fork处理 // 程序的任务是对prepare fork处理程序获取的所有锁进行解锁 //child fork处理程序在fork返回之前在子进程上下文中调用。与parent fork处理程序一样,child // fork处理程序也必须释放prepare fork处理程序获取的所有锁 #include <pthread.h> int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*chiild)(void));
线程属性的系统限制
可以通过sysconf函数查询
限制名称 | 描述 | name参数 |
PTHREAD_DESTRUCTOR _ITERATIONS |
线程退出时操作系统实现试图销毁 特定数据段的最大次数 |
_SC_THREAD_DESTRUCTOR_ ITERATIONS |
PTHREAD_KEYS_MAX | 进程可以创建的键的最大E数目 | _SC_THREAD_KEYS_MAX |
PTHRAD_STACK_MIN | 一个线程的栈可用的最小字节数 | _SC_THREAD_STACK_MIN |
PTHREAD_THREADS_MAX | 进程可以创建的最大线程数 | _SC_THREAD_THREADS_MAX |
pthread接口允许我们通过设置每个对象关联的不同属性来细调线程和同步对象的行为。通常,管理这些
属性的函数都遵循相同的模式
1)每个对象与它自己类型的属性对象进行关联(线程与线程属性关联,互斥量与互斥量属性关联等)。一个
属性对象可以代表多个属性。属性对象对应用程序来说是不透明的。这意味着应用程序并不需要了解
有关属性对象内部结构的详细细节,这样可以增强应用程序的可移植性。取而代之的是需要提供相应的
函数来管理这些属性对象
2)有一个初始化函数,把属性设置为默认值
3)还有一个销毁属性对象的函数。如果初始化函数分配了与属性对象管理的资源,销毁函数负责释放这些
资源
4)每个属性都有一个从属性对象中获取属性值的函数。由于函数成功时会返回0,失败时会返回错误编号,
所以可以通过把属性值存储在函数的某一个参数执行的内存单元中,把属性值返回给调用者
5)每个属性都有一个设置属性值的函数。在这种情况下,属性值作为参数按值传递
POSIX.1定义的线程属性
名称 | 描述 |
detachstat | 线程的分离状态属性 |
guardsize | 线程栈末尾的警戒缓冲区大小(字节) |
stackaddr | 线程栈的最低地址 |
stacksize | 线程栈的最小长度(字节) |
互斥量类型行为
互斥量类型 |
没有解锁时 重新加载? |
不占用 时解锁? |
在已解锁 时解锁? |
说明 |
PTHREAD_MUTEX _NORMAL |
死锁 | 未定义 | 未定义 |
一种标准互斥量类型,不做任何 特殊的错误检查或死锁检测 |
PTHREAD_MUTEX_ ERRORCHECK |
返回错误 | 返回错误 | 返回错误 |
此互斥量类型提供错误检查 |
PTHREAD_MUTEX_ RECURSIVE |
允许 | 返回错误 | 返回错误 |
此互斥量类型允许同一线程在互斥量解锁 之前对该互斥量进行多次加锁。递归互斥量维护 锁的计数,在解锁次数和加锁次数不相同的情况 下,不会释放锁。所以如果对一个递归互斥量 加锁两次,然后解锁一次,那么这个互斥量将 依然处于加锁状态,对它再次解锁以前不能释放 该锁。 |
PTHREAD_MUTEX_ DEFAULT |
未定义 | 未定义 | 未定义 |
此互斥量类型可以提供默认特性和行为。操作 系统再实现它的时候可以把这种类型自由的映射 到掐互斥量类型中的一种。如Linux3.2.0把这种 类型映射为普通的互斥量类型而FreeBSD则把 它映射为错误检查互斥量类型 |
重入
如果一个函数在相同 时间点可以被多个线程安全的调用,就称该函数是线程安全的
线程特定数据
线程特定数据(thread-specific data),也称为线程私有数据(thread-private data),是存储和查询某个特定
线程相关数据的一种机制。我们把这种数据称为线程特定数据或线程私有数据的原因是 希望每个线程可以
访问他们自己单独的数据副本,而不需要担心与其他线程的同步访问问题。
线程模型促进了线程中数据和属性的共享,为什么有人想在这种的模型中促进阻止共享的接口呢?
1)有时候需要维护每线程(per-thread)的数据,因为线程ID并不能保证是小而连续的整数,所以就不能简单
的分配一个每线程数据数组,用线程ID作为数组的索引。即使线程ID确实是小而连续的整数,我们可能
还希望有一些额外的保护,防止某个线程的数据与其他线程的数据相混淆
2)提供了让基于进程的接口适应多线程环境的机制,一个明显的实例就是errno,以前的接口都是进程
上下文全局可访问的整数,系统调用和库例程调用或执行失败时设置的,把它作为操作失败时负数的结果。
所以把errno定义为线程私有数据
线程和信号
每个线程都有自己的信号屏蔽字,但是信号的处理是进程中所有线程共享的
这意味着单个线程可以阻止某些信号,但当某个线程修改了与某个给定信号相关的处理行为以后,所有的
线程都必须共享这个处理行为的改变
线程和fork
子进程从父进程继承了每个互斥量,读写锁和条件变量,如果父进程包含一个以上的线程,子进程在fork
返回以后,如果紧接着不是马上调用exec的话,就需要清理锁状态
相关推荐
在Unix环境中,线程控制是高级编程中的一个重要概念,它涉及到多线程程序的设计和管理。线程控制允许程序员在单个进程中同时执行多个独立的执行流,从而提高程序的并发性和效率。以下是对《Unix环境高级编程》第十二...
《UNIX环境高级编程》详细解释了信号的概念、发送、接收和处理,以及信号在进程控制中的应用,帮助读者理解如何优雅地处理程序中断和异常情况。 此外,书中还涉及了进程环境、系统调用接口、编译和链接、动态装载、...
《UNIX环境高级编程》是一本深入探讨UNIX系统编程的权威参考书籍。它涵盖了UNIX编程的各个方面,从基础的UNIX系统结构和原理,到文件操作、进程控制、进程间通信、多线程编程、网络编程以及终端I/O和伪终端等内容。...
《UNIX环境高级编程(第3版)》在保持前一版风格的基础上,根据最新的标准对内容进行了修订和增补,反映了最新的技术发展。书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系...
《Unix环境高级编程》是一本深受程序员和系统管理员喜爱的经典之作,主要涵盖了在Unix操作系统环境下进行高级编程的各种技术和方法。这本书分为多个章节,详细讲解了Unix系统接口、进程管理、文件系统、网络通信等...
### Unix环境高级编程 第三版 知识点详解 #### 一、书籍概述与目标读者 《Unix环境高级编程》第三版是一本针对高级程序员和网络专业人士编写的实用参考书。该系列书籍由Addison-Wesley出版社创建于1990年,旨在为...
《UNIX环境高级编程》是Unix系统编程领域的一本经典之作,被誉为“圣书”,对于学习Linux开发技术的人员来说,是一本不可或缺的参考书。这本书深入讲解了在Unix环境下进行系统级编程的各种技术和细节,涵盖了从基本...
《UNIX环境高级编程》(第三版) 是一本深入讲解UNIX操作系统编程的经典著作,它由W. Richard Stevens撰写,是IT行业内广泛使用的参考资料。这本书详细介绍了如何在UNIX系统上进行高级程序设计,涵盖了从系统调用、...
- **高级编程技术**:本书重点介绍了Unix/Linux环境下的高级编程技术,包括进程管理、线程控制、网络编程等方面的内容。 #### 3. **关键章节概览** - **进程管理**:详细讲解了如何创建和管理进程,包括进程间的...
《UNIX环境高级编程》与《UNIX网络编程卷1:协议》是两本深入解析UNIX系统编程的经典著作。在深入理解这些书籍的知识点之前,我们先要了解UNIX系统的基础概念。 UNIX是一个多用户、多任务的操作系统,其设计哲学...
此书不仅涵盖了UNIX系统的基础知识,还深入讲解了高级编程技术,如进程控制、线程管理、信号处理、网络编程等关键主题。 ### 进程控制 在UNIX环境下,进程是程序执行的基本单位。书中详细阐述了如何创建、管理和...
《Unix环境高级编程》是一本深受程序员和系统管理员喜爱的经典之作,由W. Richard Stevens著述,详尽地阐述了在Unix操作系统环境下进行系统级编程的各种技术和方法。这本书旨在帮助读者深入理解Unix系统的内部工作...
《UNIX环境高级编程》是一本深受程序员和系统管理员喜爱的经典之作,主要针对那些希望深入理解UNIX操作系统,并希望在该环境中进行高效开发和系统管理的读者。这本书覆盖了UNIX系统的诸多核心概念和技术,包括进程...
UNIX环境高级编程通常涉及的内容包括UNIX系统的系统调用、标准I/O库、进程控制、信号处理、线程控制、守护进程的创建与管理、时间和日期处理、文件和目录操作、以及网络编程等多个方面。这些知识点几乎涵盖了UNIX...
7. 高级主题和最佳实践:《Unix环境高级编程》第三版也涉及一些高级主题,例如文件系统、伪终端、终端I/O控制等。同时,书中还介绍了程序设计的最佳实践,帮助开发者编写更安全、更可靠的Unix系统程序。 在《Unix...
《UNIX环境高级编程》中文第三版是一本深受程序员和系统管理员喜爱的经典著作,它深入浅出地介绍了在UNIX操作系统环境下进行程序开发的各种技术与实践。这本书涵盖了从基本的文件I/O到复杂的进程间通信,从信号处理...
在深入探讨"UNIX环境高级编程"这一主题之前,我们首先要理解UNIX系统的基础。UNIX是一种多用户、多任务的操作系统,最初由贝尔实验室的Ken Thompson、Dennis Ritchie等人开发。这个系统以其强大的命令行界面、丰富的...
《Unix环境高级编程》是一本深受程序员和系统管理员喜爱的经典之作,主要针对那些希望深入理解Unix操作系统,并希望在该环境中进行高效程序开发的读者。这本书不仅涵盖了Unix的基础知识,还详细解析了高级主题,包括...