IO进程线程 day8

发布时间:2024年01月10日

使用信号量灯集同步三个进程操作共享内存打印ABC

head.h

#ifndef __SEM_H__
#define __SEM_H__

//创建信号灯集并初始化
int create_sem(int semcount);

//申请资源 P操作
int P(int semid,int semno);

//释放资源 V操作
int V(int semid,int semno);

//删除信号灯集
int delete_sem(int semid);


#endif

test.c

#include<my_head.h>
union semun
{
   int   val;   
   struct semid_ds *buf;      
   unsigned short  *array;     
   struct seminfo  *__buf;  
};

//初始化信号灯集函数
int init_sem(int semid,int semno)
{
	union semun us;
	printf("请输入第%d号灯的初始值:",semno);
	scanf("%d",&us.val);
	getchar();
	if(semctl(semid,semno,SETVAL,us) == -1)
	{
		perror("init_sem error");
		return -1;
	}
	return 0;
}

//创建信号灯集并初始化 
int create_sem(int semcount)
{
	key_t key = ftok("/",520);
	if(key == -1)
	{
		perror("ftok error");
		return -1;
	}
	int semid = semget(key,semcount,IPC_CREAT|IPC_EXCL|0666);
	if(semid == -1)
	{
		if(errno == EEXIST)
		{
			semid = semget(key,semcount,IPC_CREAT);
			return semid;
		}
		perror("semget error");
		return -1;
	}
	for(int i=0;i<semcount;i++)
	{
		init_sem(semid,i);
	}
	return semid;
}

//申请资源 P操作
int P(int semid,int semno)
{
	struct sembuf buf;
	buf.sem_num = semno;
	buf.sem_op =  -1;
	buf.sem_flg = 0;
	if(semop(semid,&buf,1) == -1)
	{
		perror("p error");
		return -1;
	}
	return 0;
}

//释放资源 V操作
int V(int semid,int semno)
{
	struct sembuf buf;
	buf.sem_num = semno;
	buf.sem_op =  1;
	buf.sem_flg = 0;
	if(semop(semid,&buf,1) == -1)
	{
		perror("v error");
		return -1;
	}
	return 0;
}

//删除信号灯集
int delete_sem(int semid)
{
	if(semctl(semid,0,IPC_RMID) == -1)
	{
		perror("delete_sem error");
		return -1;
	}
	return 0;
}

A.c

#include<my_head.h>
#define PAGE_SIZE 4096
#include "head.h"

int main(int argc, const char *argv[])
{
	//创建信号灯集并初始化
	int semid = create_sem(3);
	//创建key值
	key_t key = ftok("/",1314);
	if(key == -1)
	{
		perror("ftok");
		return -1;
	}
	//用key值创建一个共享内存,返回shmid
	int shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0666);
	if(shmid == -1)
	{
		perror("shmget error");
		return -1;
	}
	//映射共享内存到用户空间
	char *addr = shmat(shmid,NULL,0);
	if(addr == (void *)-1)
	{
		perror("shmat error");
		return -1;
	}
	//使用共享内存
	int count = 5;
	while(count -- )
	{
		//先打印一个A
		puts("A");
		//p操作申请0号灯
		P(semid,0);
		//存放数据B
		strcpy(addr,"B");
		//v操作释放1号灯
		V(semid,1);
	}
	//取消共享内存映射
	if(shmdt(addr) == -1)
	{
		perror("shmdt error");
		return -1;
	}

	return 0;
}

B.c

#include<my_head.h>
#define PAGE_SIZE 4096
#include "head.h"

int main(int argc, const char *argv[])
{
	//创建信号灯集并初始化
	int semid = create_sem(3);
	//创建key值
	key_t key = ftok("/",1314);
	if(key == -1)
	{
		perror("ftok");
		return -1;
	}
	//用key值创建一个共享内存,返回shmid
	int shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0666);
	if(shmid == -1)
	{
		perror("shmget error");
		return -1;
	}
	//映射共享内存到用户空间
	char *addr = shmat(shmid,NULL,0);
	if(addr == (void *)-1)
	{
		perror("shmat error");
		return -1;
	}
	//使用共享内存
	int count = 5;
	while(count -- )
	{
		//p操作申请1号灯
		P(semid,1);
		//打印数据B
		printf("%s\n",addr);
		strcpy(addr,"C");
		//v操作释放2号灯
		V(semid,2);
	}
	//取消共享内存映射
	if(shmdt(addr) == -1)
	{
		perror("shmdt error");
		return -1;
	}

	return 0;
}

C.c

#include<my_head.h>
#define PAGE_SIZE 4096
#include "head.h"

int main(int argc, const char *argv[])
{
	//创建信号灯集并初始化
	int semid = create_sem(3);
	//创建key值
	key_t key = ftok("/",1314);
	if(key == -1)
	{
		perror("ftok");
		return -1;
	}
	//用key值创建一个共享内存,返回shmid
	int shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0666);
	if(shmid == -1)
	{
		perror("shmget error");
		return -1;
	}
	//映射共享内存到用户空间
	char *addr = shmat(shmid,NULL,0);
	if(addr == (void *)-1)
	{
		perror("shmat error");
		return -1;
	}
	//使用共享内存
	int count = 5;
	while(count -- )
	{
		//p操作申请2号灯
		P(semid,2);
		//打印数据C
		printf("%s\n",addr);
		//存放数据B
		strcpy(addr,"C");
		//v操作释放0号灯
		V(semid,0);
	}
	//取消共享内存映射
	if(shmdt(addr) == -1)
	{
		perror("shmdt error");
		return -1;
	}
	//删除共享内存
	if(shmctl(shmid,IPC_RMID,NULL) == -1)
	{
		perror("shmctl error");
		return -1;
	}
	//删除信号灯集
	delete_sem(semid);
	
	return 0;
}

文章来源:https://blog.csdn.net/fj199121/article/details/135514193
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。