前言
进程间通信的一种方式:信号量
提示:以下是本篇文章正文内容,下面案例可供参考
一、临界资源与临界区
同一时间段只允许一个进程或线程访问的资源叫做临界资源。
访问临界资源的代码段叫临界区。
二、信号量
信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作当信号量值为 0 时,代表没有资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V操作。信号量主要用来同步程。信号量的值如果只取 0,1,将其称为二值信号量。如果信号量的值大于 1,则称之为计数信号量
三、信号量使用方法
1.常用接口
int semget(key_t key, int nsems, int semflg);//创建或获取信号量
int semop(int semid, struct sembuf *sops, unsigned nsops);//信号量的加减操作
int semctl(int semid, int semnum, int cmd, …);//控制信号量
2.使用示例
代码如下(示例):
sem.c//
static int semid;//初始化信号量
void init_sem
{
semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
if(semid==-1)//证明1234已经创建
{
semid=semget((key_t)1234,1,IPC_CREAT|0600)//直接获取semid
{
if(semid==-1)//获取失败
{
printf("semget err\n");
return;
}
}
}
else//1234没有被创建
{
union semun a;
a.val=1;
if(semctl(semid,0,SETVAL,a)==-1)//初始化信号量
{
printf("setval err\n");
return;
}
}
}
int sem_p//减1操作
{
struct sembuf buf;
buf.sem_num=0;
buf.sem_op=-1;
buf.sem_flg=SEM_UNDO;
if(semop(semid,&buf,1)==-1)
{
printf("sem_p err\n");
return -1;
}
return 0;
}
int sem_v//加1操作
{
struct sembuf buf;
buf.sem_num=0;
buf.sem_op=1;
buf.sem_flg=SEM_UNDO;
if(semop(semid,&buf,1)==-1)
{
printf("sem_v err\n");
return -1;
}
return 0;
}
void destroy_sem()//销毁信号量
{
if(semctl(semid,0,IPC_RMID)==-1)
{
printf("destroy err\n");
}
}
a.c//打印A
int main()
{
sem_init();
for(int i=0;i<5;++i)
{
sem_p();
printf("A");
fflush(stdout);
int n=rand()%3;
sleep(n);
printf("A");//打印完第二次A证明a.c任务完成
fflush(stdout);
sem_v();
sleep(rand()%3);
}
sleep(10);//让A最后结束
destroy_sem();//销毁信号
}
b.c//打印B
int main()
{
sem_init();
for(int i=0;i<5;++i)
{
sem_p();
printf("B");
fflush(stdout);
int n=rand()%3;
sleep(n);
printf("B");//打印完第二次B证明b.c任务完成
fflush(stdout);
sem_v();
sleep(rand()%3);
}
}
2.输出结果
四、共享内存
1.什么是共享内存
共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。
2.代码示例
输出:
五、消息队列
创建一个消息队列,可以有多个程序进行消息的添加,另外多个程序进行消息的读取。消息要有具体的编号,这样接受的程序会根据编号接受相应的消息。
消息队列也是创建在内存中。当接受消息的程序将接受消息类型设置为0时,表示接受程序不按消息类型进行接受,即接受所有类型的消息。
总结
信号量可以对两个进程进行控制,使其按照一定的顺序执行。
ipcs 这个指令可以查看当前的共享内存,信号量,消息队列的内容。