APUE Chapter 12笔记:Unix下线程的控制(II)

6 篇文章 0 订阅
对于线程之间数据的同步锁,同样有着属性:

1、mutex锁
int pthread_mutexattr_init(pthread_mutexattr_t *);
int pthread_mutexattr_destroy(pthread_mutexattr_t*);
对锁进行初始化和破坏

锁有两种属性。第一种是进程间的共享。这个不是POSIX属性,然而被Single UNIX Specification所支持。属性有两种值,一个是PTHREAD_PROCESS_PRIVATE,一个是PTHREAD_PROCESS_SHARED。在后一种情况下,线程所锁定的内存可以被多个进程共享同步,然而前者是缺省值,因为前者更容易被实现。
第二种属性是mutex锁的类型,分为四种:
mutex锁的类型
 Relock without unlockUnlock when not ownedUnlock when unlocked
PTHREAD_MUTEX_NORMALdeadloclundefinedundefined
PTHREAD_MUTEX_ERRORCHECKerrorerrorerror
PTHREAD_MUTEX_RECURSIVEallowederrorerror
PTHREAD_MUTEX_DEFAULTundefinedundefinedundefined

对于RECURSIVE类型的锁,可以被锁定多次,同时,也必须解锁相应的次数。也就是说,引进了“锁定计数”的功能。
要设定锁的这种属性,调用函数:
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, int*restrict);
int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
注意在后者中mutexattr_t没有restrict限定符。如果加上了restrict限定符,可能不能够满足多线程访问的要求,因为可能有多个指针来处理这个mutexattr对象。

2、读写锁
读写锁只有一种属性,pshared

3、条件变量
条件变量也只有一种pshared属性。


函数的"thread-safe”特性
函数如果能够被多个线程同时调用,就称作“线程安全”的。POSIX 1 下如下函数不是线程安全的(参见APUE 表12.9)。如果要用的话,不妨加上mutex锁来协助。另外,对于一些函数,提供了线程安全的函数作为替代。另外对于文件,有
int ftrylockfile(FILE *);
void flockfile(FILE *);
void funlockfile(FILE *);
提供的锁是recursive的。
之所以不是线程安全的,一个重要的原因是函数内部有自己的静态存储数据。

线程的私有数据
的确,共享数据让大家伤透脑筋,不过有的时候,需要为各个线程准备不同的数据:我们不能让一群线程通过锁互相排队等待数据。
一个简单的想法是,准备一个数组。然而为了保证各个线程的数据都独立,需要为每个线程准备对应元素。而线程的编号未必很小,也不一定连续。一个解决方法是,提供一个key:
int pthread_key_create(pthread_key*, void(*destructor(void*)));
创建一个key,对于所有线程可以共享一个key,但是不同的线程key对应的数据地址是不同的。对于每个线程,初始化的地址都是NULL。另外,每个key都可以附加一个析构函数。析构函数在线程通过pthread_exit()退出时自动执行。
一个线程可以准备多个key。要除掉一个key,可以适用
int pthread_key_delete(pthread_key_t*);
为了防止重复设定key,需要有一个标志位来确定key是否已经建立。然而不能通过线程内部设定标志位的方法来达到这个目的。因为检查位和设定位两个操作不是合并的原子操作。可以采用的方法是用pthread_once
int pthread_once(pthread_once_t*,void (*initfunction) (void));
对每个pthread_once_t要先设定PTHREAD_ONCE_INIT值。多个线程对于同一个pthread_once_t,只会有一个线程执行一次。
要通过key来访问数据,可以调用
void* pthread_getspecific(pthread_key_t);
int pthread_setspecfic(pthread_key_t,const void*);


附注:上述提到的”线程的私有数据“是指,一些线程需要调用一个函数,而这个函数需要为不同的线程提供不同的数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值