设计三个程序,要求三个程序申请一块共享内存,并分别映射到各自进程的地址空间,进程A和进程B对共享内存段中的数据进行修改,然后进程C不断输出共享内存段中的数据,并观察效果,要求实现进程间的互斥,避免竞争。
进程A:
/*******************************************************************
*
* file name: A.c
* author : Dazz
* date : 2024/05/28
* function : 进程A,用于对共享内存中的数据进行修改
* note : None
*
* CopyRight (c) 2024 [email protected] All Right Reseverd
*
* *****************************************************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
char *p;
// 进程A收到信号会对共享内存段中的数据进行修改
void sighandler(int a)
{
sprintf(p, "Hello,here is processA\n");
}
int main()
{
// 打开共享内存段,如果不存在则创建,如果存在则打开
int shm_id = shmget(ftok("..", 76), 512, IPC_CREAT | IPC_EXCL | 0644);
if (-1 == shm_id)
{
// 如果存在则会报错
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
// 如存在,则打开共享内存段即可
shm_id = shmget(ftok("..", 76), 512, 0644);
if (-1 == shm_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
}
// 把共享内存段连接到进程空间
p = shmat(shm_id, NULL, 0);
if ((void *)-1 == p)
{
// 如连接失败则直接退出程序
fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
exit(2);
}
// 打印自己的PID
printf("the PID of processA is %d\n", getpid());
// 等待接收SIGUSR1的信号
signal(SIGUSR1, sighandler);
while (1);
// 销毁链接得到的虚拟地址
shmdt(p);
return 0;
}
进程B:
/*******************************************************************
*
* file name: B.c
* author : Dazz
* date : 2024/05/28
* function : 进程B,用于对共享内存中的数据进行修改
* note : None
*
* CopyRight (c) 2024 [email protected] All Right Reseverd
*
* *****************************************************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
char *p;
// 进程A收到信号会对共享内存段中的数据进行修改
void sighandler(int a)
{
sprintf(p, "Hi,here is processB\n");
}
int main()
{
// 打开共享内存段,如果不存在则创建,如果存在则打开
int shm_id = shmget(ftok("..", 76), 512, IPC_CREAT | IPC_EXCL | 0644);
if (-1 == shm_id)
{
// 如果存在则会报错
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
// 如存在,则打开共享内存段即可
shm_id = shmget(ftok("..", 76), 512, 0644);
if (-1 == shm_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
}
// 把共享内存段连接到进程空间
p = shmat(shm_id, NULL, 0);
if ((void *)-1 == p)
{
// 如连接失败则直接退出程序
fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
exit(2);
}
// 等待接收SIGUSR2的信号
signal(SIGUSR2, sighandler);
// 打印自己的PID
printf("the PID of processA is %d\n", getpid());
while (1);
// 销毁链接得到的虚拟地址
shmdt(p);
return 0;
}
进程C:
/*******************************************************************
*
* file name: C.c
* author : Dazz
* date : 2024/05/28
* function : 进程C,用于读取并输出对共享内存中的数据
* note : None
*
* CopyRight (c) 2024 [email protected] All Right Reseverd
*
* *****************************************************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main()
{
// 打开共享内存段,如果不存在则创建,如果存在则打开
int shm_id = shmget(ftok("..", 76), 512, IPC_CREAT | IPC_EXCL | 0644);
if (-1 == shm_id)
{
// 如果存在则会报错
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
// 如存在,则打开共享内存段即可
shm_id = shmget(ftok("..", 76), 512, 0644);
if (-1 == shm_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
}
// 把共享内存段连接到进程空间
char *p = shmat(shm_id, NULL, 0);
if ((void *)-1 == p)
{
// 如连接失败则直接退出程序
fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
exit(2);
}
// 手动输入进程A和进程B的pid
int PidA, PidB;
printf("please input the PID of processA\n");
scanf("%d", &PidA);
printf("please input the PID of processB\n");
scanf("%d", &PidB);
while (1)
{
// 给进程A发送信号
kill(PidA, SIGUSR1);
sleep(2);
// 输出读到的数据
printf("%s\n", p);
// 给进程B发送信号
kill(PidB, SIGUSR2);
sleep(2);
// 输出读到的数据
printf("%s\n", p);
}
// 销毁链接得到的虚拟地址
shmdt(p);
return 0;
}
标签:练习题,共享内存,shmget,errno,shm,include,id
From: https://www.cnblogs.com/Dazz24/p/18217784