设计三个程序,三个程序申请一块共享内存,并分别映射到各自进程的地址空间,进程A和进程B对共享内存段中的数据进行修改,然后进程B不断输出共享内存段中的数据,实现进程间的互斥,避免竞争。
/********************************************************************************
*
*
* 使用信号对共享内存进行互斥访问
* author:jindouliu2024@163.com
* date:2025.5.8
*
*
* Copyright (c) 2024-2025 jindouliu2024@163.com All right Reserved
* ******************************************************************************/
//进程A
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
char *shm_map;
int id,i=0;
void sig_handler(int signal)
{
//如果是接受到的信号是SIGUSR1,则执行
if(signal == SIGUSR1){
i++;
//向内存写入数据
sprintf(shm_map,"shm_a.c data = %d\n",i);
printf("请输入进程id:");
scanf("%d",&id);
//给进程B发送信号
kill(id,SIGUSR2);
}
}
int main()
{
//设置键值
key_t key = ftok(".",2);
//创建一块共享内存空间
int shm_id = shmget(key,256,IPC_CREAT|IPC_EXCL|0644);
if(shm_id == -1){
printf("shmget error\n");
shm_id = shmget(key,256,0644);
}
//连接映射空间,并写入数据
shm_map = (char *)shmat(shm_id,NULL,0);
printf("running a\n");
signal(SIGUSR1,sig_handler);
while(1);
return 0;
}
//进程B
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
char *shm_map;
int id;
//信号处理函数
void sig_handler(int signal)
{
//如果是接受到的信号是SIGUSR2,则执行
if(signal == SIGUSR2){
//从内存中读取数据
printf("%s\n",shm_map);
}
printf("请输入进程id:");
scanf("%d",&id);
//给进程A或者进程B发送信号
kill(id,SIGUSR1);
}
int main()
{
//设置键值
key_t key = ftok(".",2);
//创建一块共享内存空间
int shm_id = shmget(key,256,IPC_CREAT|IPC_EXCL|0644);
if(shm_id == -1){
printf("shmget error\n");
shm_id = shmget(key,256,0644);
}
//连接映射空间,并读取数据
shm_map = (char *)shmat(shm_id,NULL,0);
printf("请输入进程id:");
scanf("%d",&id);
kill(id,SIGUSR1);
signal(SIGUSR2,sig_handler);
while(1){
}
shmdt(shm_map);
return 0;
}
//进程C
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
char *shm_map;
int id,i=100;
void sig_handler(int signal)
{
//如果是接受到的信号是SIGUSR1,则执行
if(signal == SIGUSR1){
i--;
//向内存写入数据
sprintf(shm_map,"shm_a.c data = %d\n",i);
printf("请输入进程id:");
scanf("%d",&id);
//给进程B发送信号
kill(id,SIGUSR2);
}
}
int main()
{
//设置键值
key_t key = ftok(".",2);
//创建一块共享内存空间
int shm_id = shmget(key,256,IPC_CREAT|IPC_EXCL|0644);
if(shm_id == -1){
printf("shmget error\n");
shm_id = shmget(key,256,0644);
}
//连接映射空间,并写入数据
shm_map = (char *)shmat(shm_id,NULL,0);
printf("running c\n");
signal(SIGUSR1,sig_handler);
while(1);
return 0;
}