linux posix 线程池_多线程同步之 POSIX 同步

信号量

Linux 下有信号量的API有两个,一个是之前讲的System V IPC信号量,现在讨论的是POSIX的信号量。

#include

int sem_init(sem_t *sem, int pshared, unsigned int value);

int sem_destroy(sem_t* sem);

int sem_wait(sem_t* sem);

int sem_trywait(sem_t * sem);

int sem_post(sem_t* sem);

所有这些接口的第一个参数sem 都指向一个被操作的信号量。

sem_init 中, pshared参数指定信号量的类型。如果其值为0,那么信号量就是当前进程的局部信号量。否则就是多个进程共享的。value 表示信号量的初始值。

sem_destroy 函数可用于销毁一个信号量,以释放其占有的内核资源。如果销毁一个正在被其他线程等待的信号量,后果不可预知。

sem_wait 函数以原子操作将信号量减1。如果信号量值为0,那么sem_wait 阻塞,直到这个信号量具有非0 值。

sem_trywait 是sem_wait的非阻塞版本。

sem_post函数以原子操作将信号量加1。如果信号量大于0,正在调用sem_wait的函数阻塞的线程将被唤醒。

互斥锁

POSIX互斥锁是在线程同步中重要的工具,概念不在赘述。

POSIX互斥锁相关的函数主要有5个:

#include

int pthread_mutex_init(pthread_mutex_t* mutex,

const pthread_attr_t * mutex_attr);

int pthread_mutex_destroy(pthread_mutex_t* mutex);

int pthread_mutex_lock(pthread_mutex_t* mutex);

int pthread_mutex_trylock(pthread_mutex_t* mutex);

int pthread_mutex_unlock(pthread_mutex_t* mutex);

这些参数的第一个参数指向要操作的目标互斥锁。

pthread_mutex_init 函数用于初始化互斥锁, mutex_attr参数指定互斥锁的属性。如果它使用NULL,表示是用默认的属性。

pthread_mutex_destroy 函数用于销毁一个互斥锁,以释放被其占有的内核资源,销毁一个已经加锁的互斥锁将导致不可预知的后果。

pthread_mutex_lock 函数以原子操作的方式给互斥锁加锁。如果目标互斥锁被锁住,那么pthread_mutex_lock将被阻塞,直到互斥锁被解锁。

pthread_mutex_trylock函数是pthread_mutex_lock的非阻塞版本。它始终会立即返回,不管互斥锁被加锁还是没加锁。

pthread_mutex_unlock 函数以原子操作的方式给一个互斥锁解锁。如果此时有其他线程正在等待这个互斥锁,这些线程会获取到它。

条件变量

一般的互斥锁和条件变量一起使用。

#include

int pthread_cond_init(pthread_cond_t* cond,

const pthread_condattr_t* cond_attr);

int pthread_cond_destroy(pthread_cond_t* cond);

int pthread_cond_broadcast(pthread_cond_t* cond);

int pthread_cond_signal(pthread_cond_t* cond);

int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);

这些操作的第一个参数cond指向要操作的目标条件变量,条件变量的类型是pthread_cond_t。

pthread_cond_init 函数用于初始化条件变量。cond_attr参数指定条件变量的属性。

pthread_cond_destroy 函数用于销毁条件变量,释放内核资源。销毁一个正在被等待的条件变量将失败并返回EBUSY。

pthread_cond_broadcast 函数以广播的方式唤醒所有等待目标条件变量的线程。

pthread_cond_signal 用于唤醒一个等待目标条件变量的线程。至于那个线程被唤醒,这是线程调度策略的问题。

pthread_cond_wait 函数用于等待目标条件变量。 mutex参数是用于保护条件变量的互斥锁,以保证pthread_cond_wait操作的原子性。在调用pthread_cond_wait前,必须确保互斥量mutex已经加锁,否则将导致不可预知的后果。

pthread_cond_wait一般干了三件事:

1、给互斥锁解锁

2、把调用线程投入睡眠,直到另外某个线程就本条件调用signal。

3、然后,在返回前重新给互斥锁上锁(没有获得锁时一直阻塞在这里)

上面的函数成功返回0,失败返回错误码。

线程和信号

和进程一样,线程也可以设置自己的信号掩码。

#include

#include

int pthread_sigmask(int how, const sigset_t* newmask,

sigset_t* oldmask);

由于进程中的所有线程共享该进程的信号。所以线程库将根据线程掩码觉得把信号发送给哪个具体的线程。

信号的处理函数在进程中的线程是共享的,一旦一个线程注册了新的信号处理函数,那么就会影响其他线程的执行,所以,一般我们在编程的时候都会有一个专门的线程来处理所有的信号。

在某个线程中调用sigwait来等待信号处理:

int sigwait(const sigset_t * set ,int* sig);

set表示要处理的信号集合,他们可以可以认为是主线程中的信号掩码。

sig 指向的整数用于存储该函数的返回的信号值。

读写锁

读写锁与互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态,要么是不加锁状态,而且一次只有一个线程对其加锁。读写锁可以有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可用同时占有读模式的读写锁。读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的。

LINUX 读写锁是写者优先

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值