PV操作是一种实现进程互斥与同步的有效方法。PV操作与信号量的处理相关,P表示通过的意思,V表示释放的意思。
互斥和同步概念:
互斥指的是控制两个进度相互排斥,不能同时运行。
同步指的是控制两个进度让他有先后顺序,次序可控。
例子:生产者和消费者的关系,需要调用资源,用共享内存。
信号量
作用:用于保护线程或进程之间的共享资源与实现同步与互斥。
有名信号量
作用:用于保护共享内存,防止资源抢占和实现同步与互斥。
消费者
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
int main()
{
//创建一个信号量
sem_t *s=sem_open("/mysem",O_CREAT,0777,1);
if(s != SEM_FAILED)
{
printf("创建信号量成功\n");
}else
{
perror("创建信号量失败\n");
}
sem_t *s1=sem_open("/mysem1",O_CREAT);
if(s1 != SEM_FAILED)
{
printf("创建信号量成功\n");
}else
{
perror("创建信号量失败\n");
}
//获取信号量的值
int sval=0;
sem_getvalue(s,&sval);
printf("s当前信号量的值 %d\n",sval);
sval=0;
sem_getvalue(s1,&sval);
printf("s1当前信号量的值 %d\n",sval);
//1.创建共享内存对象
key_t key=ftok("/",100);
if(key < 0)
{
perror("create fail:");
return -1;
}
//2.获取共享内存描述符
int shm_id = shmget(key,1024,IPC_CREAT|0777);
if(shm_id < 0)
{
perror("shmget fail:");
return -1;
}
//3.映射共享内存
int *p=shmat(shm_id,NULL,0);
//处理数据
while (1)
{
//进行P 操作,申请资源
sem_wait(s);
if(*p%2 == 0)
{
printf("处理偶数=%d\n",*p);
}else
{
printf("处理非偶数=%d\n",*p);
}
//释放S1
sem_post(s1);
}
//关闭信号量
sem_close(s);
sem_close(s1);
//销毁有名信号量
sem_unlink("/mysem");
sem_unlink("/mysem1");
}
生产者
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
int main()
{
//创建一个信号量
sem_t *s=sem_open("/mysem",O_CREAT,0777,1);
if(s != SEM_FAILED)
{
printf("创建信号量成功\n");
}else
{
perror("创建信号量失败\n");
}
sem_t *s1=sem_open("/mysem1",O_CREAT,0777,0);
if(s1 != SEM_FAILED)
{
printf("创建信号量成功\n");
}else
{
perror("创建信号量失败\n");
}
//获取信号量的值
int sval=0;
sem_getvalue(s,&sval);
printf("s当前信号量的值 %d\n",sval);
sem_getvalue(s1,&sval);
printf("s1当前信号量的值 %d\n",sval);
//定义一个数据
int data=0;
//1.创建共享内存对象
key_t key=ftok("/",100);
if(key < 0)
{
perror("create fail:");
return -1;
}
//2.获取共享内存描述符
int shm_id = shmget(key,1024,IPC_CREAT|0777);
if(shm_id < 0)
{
perror("shmget fail:");
return -1;
}
//释放 s
sem_post(s);
//3.映射共享内存
int *p=shmat(shm_id,NULL,0);
*p = data++;
while (1)
{
//申请s1
sem_wait(s1);
//不断生产数据
*p = data++;
printf("生产数据 %d\n",*p);
//释放资源
sem_post(s); //V 操作 释放
}
}