Linux 多线程信号量同步

时间:2023-02-21 21:43:47

PV原子操作

P操作:

  • 如果有可用的资源(信号量值>0),则此操作所在的进程占用一个资源(此时信号量值减1,进入临界区代码);
  • 如果没有可用的资源(信号量值=0),则此操作所在的进程被阻塞直到系统将资源分配给该进程(进入等待队列,一直等到资源轮到该进程)。

V操作:

  • 如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞进程;如果没有进程等待它,则释放一个资源(即信号量值加1)。

模型

#include <semaphore.h>
sem_t sem //定义信号量
sem_init() //初始化信号量
sem_wait() //获取信号量,信号量的数值-1
访问共享资源
sem_post() //释放一个信号量,及信号量的数值+1
sem_destroy() //如果不再使用信号量,则销毁信号量

函数和POSIX IPC的信号量相同

例子

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include<semaphore.h>
char* buf[5];
int pos;
//1.定义信号量
sem_t sem;
void* task(void* pv){
//3.使用信号量,-1
sem_wait(&sem);

//4.访问共享内存
buf[pos]=(char*)pv;
sleep(1);
pos++;

//5.使用信号量进行解锁
sem_post(&sem);
}
main(){
//2.初始化信号量
sem_init(&sem,0,1);

pthread_t thread;
pthread_create(&thread,NULL,task,(void*)"zhangfei");
pthread_t thread2;
pthread_create(&thread2,NULL,task,(void*)"guanyu");

pthread_join(thread,NULL);
pthread_join(thread2,NULL);

//打印字符指针数组中的有效数据
int i=0;
for(i=0;i<pos;i++){
printf("%s ",buf[i]);
}
printf("\n");
//6.如果不再使用则销毁信号量
sem_destroy(&sem);
return 0;
}