线程间的通信
线程共享同一个进程的地址空间,通信非常方便,但也要防止处理数据时的干扰。
因为做任何事总有个先来后到吧~
so就需要一个同步互斥机制来保证数据的原子性。
什么是同步?什么是互斥?
间接相互制约可以称为互斥,线程A在使用打印机时,其它线程都要等待。
直接相互制约可以称为同步,如有线程A将计算结果提供给线程B作进一步处理,那么线程B在线程A将数据送达之前都将处于阻塞状态。
下面四种方法都属于同步互斥机制,所以原理也差不远
信号量
sem_init()初始化信号量
int sem_init (sem_t *sem, int pshared, unsigned int value)
sem_t *sem :为指向信号量结构的一个指针;
int pshared:pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;
int value:给出了信号量的初始值,实际上就是PV的值
返回值: 成功:0,失败:-1
sem_wait() //用来阻塞当前线程直到信号量sem的值大于0,用来减一操作
#include <semaphore.h>
int sem_wait(sem_t *sem);
sem_t *sem:为指向信号量结构的一个指针
返回值: 成功: 0 失败:-1
sem_post()用来增加信号量的值
#include <semaphore.h>
int sem_post( sem_t *sem )
sem_t *sem:为指向信号量结构的一个指针
返回值: 成功:0 失败:-1
sem_destroy() //用来释放信号量sem
#include <semaphore.h>
int sem_destroy(sem_t *sem)
sem_t *sem:为指向信号量结构的一个指针
返回值: 成功:0 失败:-1
int sem_init (sem_t *sem, int pshared, unsigned int value)
sem_t *sem :为指向信号量结构的一个指针;
int pshared:pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;
int value:给出了信号量的初始值,实际上就是PV的值
返回值: 成功:0,失败:-1
sem_wait() //用来阻塞当前线程直到信号量sem的值大于0,用来减一操作
#include <semaphore.h>
int sem_wait(sem_t *sem);
sem_t *sem:为指向信号量结构的一个指针
返回值: 成功: 0 失败:-1
sem_post()用来增加信号量的值
#include <semaphore.h>
int sem_post( sem_t *sem )
sem_t *sem:为指向信号量结构的一个指针
返回值: 成功:0 失败:-1
sem_destroy() //用来释放信号量sem
#include <semaphore.h>
int sem_destroy(sem_t *sem)
sem_t *sem:为指向信号量结构的一个指针
返回值: 成功:0 失败:-1
互斥锁
pthread_mutex_init()互斥锁初始化
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t *restrict mutex:互斥锁名
const pthread_mutexattr_t *restrict attr:互斥锁属性
// NULL表示缺省属性返回值: 成功:0 失败:非0
互斥锁销毁:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
pthread_mutex_t *restrict mutex:互斥锁名
返回值: 成功:0 失败:非0
int pthread_mutex_lock(pthread_mutex_t *mutex); //加锁
互斥锁销毁:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
pthread_mutex_t *restrict mutex:互斥锁名
返回值: 成功:0 失败:非0
int pthread_mutex_lock(pthread_mutex_t *mutex); //加锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁
读写锁 具体干嘛的 //http://blog.chinaunix.net/uid-27177626-id-3791049.html
读锁可以加多个读锁
写锁只能一个锁,用完要解锁(互斥锁)
pthread_rwlock_init()读写锁初始化
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);
返回值: 成功:0 失败:非0
写锁只能一个锁,用完要解锁(互斥锁)
pthread_rwlock_init()读写锁初始化
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);
返回值: 成功:0 失败:非0
pthread_rwlock_t *restrict rwlock:读写锁名
const pthread_rwlockattr_t *restrict attr:锁的属性,NULL
pthread_rwlock_rdlock()读锁
#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
返回值 : 成功:0
失败:非0
pthread_rwlock_t *rwlock:读写锁名
写锁
#include <pthread.h>
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
返回值 : 成功:0
失败:非0
pthread_rwlock_t *rwlock:读写锁名
pthread_rwlock_unlock()解锁
#include <pthread.h>
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
返回值 : 成功:0
失败:非0
pthread_rwlock_t *rwlock:读写锁名
pthread_rwloc k_destroy()销毁读写锁
#include <pthread.h>
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
返回值: 成功:0
失败:非0
pthread_rwlock_t *rwlock:读写锁名
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
pthread_rwlock_t rwlock;
void printf_char(char *string)
{
char *p = string;
while(*p != '\0')
{
fprintf(stderr,"%c",*p);
usleep(500);
p++;
}
printf("\n");
}
void *fun1(void *arg)
{
pthread_rwlock_wrlock(&rwlock);//写锁-->互斥锁
printf_char("GSDGLOVGSDQLDSFD4GF5DF75DA5W");
pthread_rwlock_unlock(&rwlock);//解锁
pthread_exit(NULL);
}
void *fun2(void *arg)
{
pthread_rwlock_wrlock(&rwlock);//写锁
printf_char("sddscxlvjslejslvslflsljflseflksd");
pthread_rwlock_unlock(&rwlock);//解锁
pthread_exit(NULL);
}
int main(void)
{
pthread_t tid1,tid2;
pthread_rwlock_init(&rwlock,NULL);
pthread_create(&tid1,NULL,&fun1,NULL);
pthread_create(&tid2,NULL,&fun2,NULL);
sleep(2);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_rwlock_destroy(&rwlock);
}
条件变量
是和互斥锁一起作用的,适用的场景是在临界资源中需要较长时间去等待某些条件就可以用pthread_cond_wait(来暂时释放互斥锁),以便让别的线程得到锁以执行
pthread_cond_broadcast(广播所有)pthread_cond_signal(单个)
pthread_cond_init()条件变量初始化
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
返回值: 成功:0
失败:非0
pthread_cond_t *restrict cond:条件变量
const pthread_condattr_t *restrict attr:条件变量属性 ,设NULL
pthread_cond_destroy()销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
返回值: 成功:0
失败:非0
pthread_cond_t *restrict cond:条件变量
通知条件变量
#include <pthread.h>
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
条件变量等待
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
返回值: 成功:0
失败:非0
pthread_cond_t *restrict cond:条件变量名
pthread_mutex_t *restrict mutex:互斥锁名