设计一个程序,作为进程A,进程A专门创建一个信号量集,要求信号量集中有1个信号量,对信号量集合中的信号量进行设置,要求集合中的信号量的初值为1,然后再设计2个程序,分别是进程B和进程C,要求进程B和进程C使用进程A创建的信号量集合中的信号量实现互斥访问。 提示:进程A、进程B、进程C需要使用共享内存作为临界资源的访问。
程序A
/*******************************************************************
*
* file name: semA.c
* author : Dazz
* date : 2024/05/28
*
* function : 进程A,进程A专门创建一个信号量集,要求信号量集中有1个信
* 号量,对信号量集合中的信号量进行设置,要求集合中的信号量
* 的初值为1
*
* note : 设计一个程序,作为进程A,进程A专门创建一个信号量集,要求
* 信号量集中有1个信号量,对信号量集合中的信号量进行设置,要
* 求集合中的信号量的初值为1,然后再设计2个程序,分别是进程B
* 和进程C,要求进程B和进程C使 用进程A创建的信号量集合中的信
* 号量实现互斥访问。 提示:进程A、进程B、进程C需要使用共享
* 内存作为临界资源的访问。
*
* 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/shm.h>
#include <signal.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
union semun
{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
int main()
{
// 创建信号量级,如果不存在则创建,如果存在则打开
int sem_id = semget(ftok("..", 76), 1, IPC_CREAT | IPC_EXCL | 0644);
if (-1 == sem_id)
{
// 如果存在则会报错
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
// 如存在,则打开共享内存段即可
sem_id = semget(ftok("..", 76), 1, 0644);
if (-1 == sem_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
// 创建管理信号量级的联合体
union semun sem_ctl;
// 对信号量值进行赋值
sem_ctl.val = 1;
// 定义一个变量来接收semctl的返回值
int semstl_rev;
// 用semctl对信号量值进行赋值
if ((semstl_rev = semctl(sem_id, 0, SETVAL, sem_ctl) == -1))
{
// 如果存在则会报错
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
exit(2);
}
}
// 创建共享内存段,如果不存在则创建,如果存在则打开
int shm_id = shmget(ftok("..", 76), 1, 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), 4, 0644);
if (-1 == shm_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
exit(3);
}
}
// 设置信号量并初始化
struct sembuf sops;
sops.sem_num = 0; // 信号量集中的信号量元素的下标
sops.sem_op = 1; // P\V操作
sops.sem_flg = 0; // 默认
// 使用semop函数对信号量集进行操作
if (semop(sem_id, &sops, 1) == -1)
{
fprintf(stderr, "shmget error, errno: %d, %s\n", errno, strerror(errno));
exit(4);
}
// 把共享内存段连接到进程空间
int *p = (int *)shmat(shm_id, NULL, 0);
if ((void *)-1 == p)
{
// 如连接失败则直接退出程序
fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
exit(5);
}
// 把一个整数存储到共享内存里
*p = 0;
return 0;
}
进程B
/*******************************************************************
*
* file name: semB.c
* author : Dazz
* date : 2024/05/28
*
* function : 进程B,进程B和进程C使用进程A创建的信号量集合中的信号量
* 实现互斥访问。
*
* note : 设计一个程序,作为进程A,进程A专门创建一个信号量集,要求
* 信号量集中有1个信号量,对信号量集合中的信号量进行设置,要
* 求集合中的信号量的初值为1,然后再设计2个程序,分别是进程B
* 和进程C,要求进程B和进程C使 用进程A创建的信号量集合中的信
* 号量实现互斥访问。 提示:进程A、进程B、进程C需要使用共享
* 内存作为临界资源的访问。
*
* 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>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
/******************************************************
*
* name : P
* function : 实现P操作
* argument
* @sops :结构体的地址
* @sem_id :共享内存的标识符
*
* retval : void
* author : Dazz
* date : 2024/5/28
* note : None
*
* *******************************************************/
void P(struct sembuf *sops, int sem_id)
{
sops->sem_op = -1;
if ((semop(sem_id, sops, 1)) == -1)
{
printf("111\n");
fprintf(stderr, "semop error, errno: %d, %s\n", errno, strerror(errno));
exit(3);
printf("22222\n");
}
}
/******************************************************
*
* name : V
* function : 实现V操作
* argument
* @sops :结构体的地址
* @sem_id :共享内存的标识符
*
* retval : void
* author : Dazz
* date : 2024/5/28
* note : None
*
* *******************************************************/
void V(struct sembuf *sops, int sem_id)
{
sops->sem_op = 1;
if ((semop(sem_id, sops, 1)) == -1)
{
fprintf(stderr, "semop error, errno: %d, %s\n", errno, strerror(errno));
exit(4);
}
}
int main()
{
// 打开共享内存段,如果不存在则创建,如果存在则打开
int shm_id = shmget(ftok("..", 76), 1, 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), 4, 0644);
if (-1 == shm_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
}
// 把共享内存段连接到进程空间
int *p = (int *)shmat(shm_id, NULL, 0);
if ((void *)-1 == p)
{
// 如连接失败则直接退出程序
fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
exit(2);
}
// 打开信号量级
int sem_id = semget(ftok("..", 76), 1, IPC_CREAT | IPC_EXCL | 0644);
if (-1 == sem_id)
{
// 如果存在则会报错
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
// 如存在,则打开共享内存段即可
sem_id = semget(ftok("..", 76), 1, 0644);
if (-1 == sem_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
// 对结构体进行初始化
struct sembuf sops;
memset(&sops, 0, sizeof(sops));
while (1)
{
// P操作
P(&sops, sem_id);
// 修改共享内存里的数据
(*p)++;
sleep(2);
// V操作
V(&sops, sem_id);
}
return 0;
}
}
进程C
/*******************************************************************
*
* file name: semB.c
* author : Dazz
* date : 2024/05/28
*
* function : 进程C,进程B和进程C使用进程A创建的信号量集合中的信号量
* 实现互斥访问。
*
* note : 设计一个程序,作为进程A,进程A专门创建一个信号量集,要求
* 信号量集中有1个信号量,对信号量集合中的信号量进行设置,要
* 求集合中的信号量的初值为1,然后再设计2个程序,分别是进程B
* 和进程C,要求进程B和进程C使 用进程A创建的信号量集合中的信
* 号量实现互斥访问。 提示:进程A、进程B、进程C需要使用共享
* 内存作为临界资源的访问。
*
* 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>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
struct sembuf sops;
/******************************************************
*
* name : P
* function : 实现P操作
* argument
* @sem_id :共享内存的标识符
*
* retval : void
* author : Dazz
* date : 2024/5/28
* note : None
*
* *******************************************************/
void P(int sem_id)
{
sops.sem_op = -1;
if (semop(sem_id, &sops, 1) == -1)
{
fprintf(stderr, "semop error, errno: %d, %s\n", errno, strerror(errno));
exit(3);
}
}
/******************************************************
*
* name : V
* function : 实现V操作
* argument
* @sem_id :共享内存的标识符
*
* retval : void
* author : Dazz
* date : 2024/5/28
* note : None
*
* *******************************************************/
void V(int sem_id)
{
sops.sem_op = 1;
if (semop(sem_id, &sops, 1) == -1)
{
fprintf(stderr, "shmget error, errno: %d, %s\n", errno, strerror(errno));
exit(4);
}
}
int main()
{
// 打开共享内存段,如果不存在则创建,如果存在则打开
int shm_id = shmget(ftok("..", 76), 1, 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), 4, 0644);
if (-1 == shm_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "shmget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
}
// 把共享内存段连接到进程空间
int *p = (int *)shmat(shm_id, NULL, 0);
if ((void *)-1 == p)
{
// 如连接失败则直接退出程序
fprintf(stderr, "shmat fail!,error: %d, %s\n", errno, strerror(errno));
exit(2);
}
// 打开信号量级
int sem_id = semget(ftok("..", 76), 1, IPC_CREAT | IPC_EXCL | 0644);
if (-1 == sem_id)
{
// 如果存在则会报错
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
// 如存在,则打开共享内存段即可
sem_id = semget(ftok("..", 76), 1, 0644);
if (-1 == sem_id)
{
// 如打开失败则直接退出程序
fprintf(stderr, "semget fail!,error: %d, %s\n", errno, strerror(errno));
exit(1);
}
// 对结构体进行初始化
memset(&sops, 0, sizeof(sops));
while (1)
{
// P操作
P(sem_id);
// 修改共享内存里的数据
printf("this is what I read from shm:%d\n", *p);
sleep(2);
// V操作
V(sem_id);
}
return 0;
}
}
标签:练习题,共享内存,errno,信号量,进程,sem,include,id
From: https://www.cnblogs.com/Dazz24/p/18218902