线程间通信 线程共享同一进程的地址空间 优点:线程间通信很容易 通过全局变量交换数据 缺点:多个线程访问共享数据时需要同步或互斥机制 线程通信 - 同步 同步指的是多个任务按照约定的先后次序互相配合完成一件事情 1968年,Edsgar Dijkstra基于信号量的概念提出了一种同步机制 有信号量来决定线程是继续运行还是阻塞等待 信号量(灯) 信号量代表某一类资源,其值表示系统中该资源的数量 信号量是一个受保护的变量,只能通过三种操作来访问 初始化 P操作(申请资源) V操作(释放资源) 信号量 - P/V操作 P(S)含义如下: if(信号量的值大于0){ 申请资源的任务继续运行; 信号量的值减一; }else{ 申请资源的任务阻塞; } V(S)含义如下: 信号量的值加一; if(有任务在等待资源){ 唤醒等待的任务,让其继续运行; } Posix 信号量 posix中定义了两类信号量: 无名信号量(基于内存的信号量) 有名信号量 pthread库常用的信号量操作函数如下: int sem_init(sem_t *sem,int pshared,unsigned int value); int sem_wait(sem_t *sem);//P操作 int sem_post(sem_t *sem);//V操作 信息量初始化 - sem_init #include<semaphore.h> int sem_init(sem_t *sem,int pshared,unsigned int value); 成功时返回0,失败时返回EOF sem 指向要初始化的信号量对象 pshared 0-线程间 1-进程间 value 信号量初值 信号量 - P/V操作 #include<semaphore.h> int sem_wait(sem_t *sem);//P操作 int sem_post(sem_t *sem);//V操作 成功时返回0,失败时返回EOF sem 指向要操作的信号量对象 线程通信 - 互斥 临界资源 一次只允许一个任务(进程、线程)访问的共享资源 临界区 访问临界资源的代码 互斥机制 mutex互斥锁 任何访问临界资源前申请锁,访问完后释放锁 互斥锁初始化 - pthread_mutex_init #include<pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_t *attr); 成功时返回0,失败时返回错误码 mutex 指向要初始化的互斥锁对象 attr互斥锁属性,NULL表示缺省属性 申请锁 - pthread_mutex_lock #include<pthread.h> int pthread_mutex_lock(pthread_mutex_t *mutex); 成功时返回0,失败时返回错误码 mutex 指向要初始化的互斥锁对象 如果无法获得锁,任务阻塞,直到获得锁 释放锁 - pthread_mutex_unlock #include<pthread.h> int pthread_mutex_unlock(pthread_mutex_t *mutex); 成功时返回0,失败时返回错误码 mutex 指向要初始化的互斥锁对象 执行完临界区要及时释放锁