shm信号灯集打印ABC&&mq传输结构体

shm信号灯集打印ABC&&mq传输结构体_第1张图片

 01msgsnd

#include 
#define MSGSZ (sizeof(Msginfo) - sizeof(long))
typedef struct
{
	long msgtype;
	struct
	{
		char name[16];
		char age[4];
	};
	
}Msginfo;

int main(int argc, const char *argv[])
{

	//获取key值
	key_t key;
	if ((key = ftok("/", 'm')) == -1)
	{
		perror("ftok");
	}

	//创建一个消息队列
	int msgid;
	if ((msgid = msgget(key, IPC_CREAT|0664)) == -1)
	{
		perror("msgget");
		return -1;
	}

	Msginfo msg = {.msgtype = 10};

	while (1)
	{
		//输入姓名年龄
		printf("请输入姓名:");
		fgets(msg.name, sizeof(msg.name), stdin);
		msg.name[strlen(msg.name) - 1] = '\0'; //换行变成结尾
		printf("请输入年龄:");
		fgets(msg.age, sizeof(msg.age), stdin);
		msg.age[strlen(msg.age) - 1] = '\0';

		if (msgsnd(msgid, &msg, MSGSZ, 0) == -1)
		{
			perror("msgsnd");
			return -1;
		}

		if (strcmp(msg.name, "quit") == 0)
		{
			break;
		}


	}

	msgctl(msgid, IPC_RMID, NULL);



	return 0;
}

02msgrcv.c

#include 
#define MSGSZ (sizeof(Msginfo) - sizeof(long))
typedef struct
{
	long msgtype;
	struct
	{
		char name[16];
		char age[4];
	};
	
}Msginfo;

int main(int argc, const char *argv[])
{

	//获取key值
	key_t key;
	if ((key = ftok("/", 'm')) == -1)
	{
		perror("ftok");
	}

	//创建一个消息队列
	int msgid;
	if ((msgid = msgget(key, IPC_CREAT|0664)) == -1)
	{
		perror("msgget");
		return -1;
	}

	Msginfo msg = {.msgtype = 10};

	while (1)
	{
		
		if (msgrcv(msgid, &msg, MSGSZ, 0, 0) == -1)
		{
			perror("msgrcv");
			return -1;
		}

		printf("name = %s, age = %s\n", msg.name, msg.age);


		if (strcmp(msg.name, "quit") == 0)
		{
			break;
		}


	}




	return 0;
}

打印abc

shm信号灯集打印ABC&&mq传输结构体_第2张图片

 A.c

#include 
#include "sem.h"

#define SHMSZ 4096
#define COUNT 3

int main(int argc, const char *argv[])
{
	//1、定义一个信号量id
	int semid = sem__init(COUNT);
	//定义key值
	key_t key;
	if ((key = ftok("/", 'm')) == -1)
	{
		perror("ftok");
		return -1;
	}

	//定义共享内存id
	int shmid;
	//创建共享内存
	if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0664)) == -1)
	{
		perror("shmget");
		return -1;
	}

	//将创建好的共享内存映射到该程序中
	char *shmaddr;
	shmaddr = shmat(shmid, NULL, 0);


	while (1)
	{
		//2、申请2号灯的资源
		P(semid, 2);

		//向共享内存中读取数据
		shmaddr[0] = 'A';

		//3、释放0号灯的资源
		V(semid, 0);
	}


	//取消映射
	shmdt(shmaddr);



	return 0;
}

B.c

#include 
#include "sem.h"

#define SHMSZ 4096

int main(int argc, const char *argv[])
{
	//1、定义一个信号量id
	int semid = sem__init();
	//定义key值
	key_t key;
	if ((key = ftok("/", 'm')) == -1)
	{
		perror("ftok");
		return -1;
	}

	//定义共享内存id
	int shmid;
	//创建共享内存
	if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0664)) == -1)
	{
		perror("shmget");
		return -1;
	}

	//将创建好的共享内存映射到该程序中
	char *shmaddr;
	shmaddr = shmat(shmid, NULL, 0);


	//打印地址
	/*printf("shmaddr = %d\n", *shmaddr);*/

	while (1)
	{
		//2、申请0号灯的资源
		P(semid, 0);

		//向共享内存中读取数据
	
		shmaddr[1] = 'B';

		//3、释放1号灯的资源
		V(semid, 1);
	}

	//取消映射
	shmdt(shmaddr);

	//删除共享内容
	shmctl(shmid, IPC_RMID, NULL);

	//4、删除信号灯集
	sem_del(semid);

	return 0;
}

C.c

#include 
#include "sem.h"

#define SHMSZ 4096
#define COUNT 3

int main(int argc, const char *argv[])
{
	//1、定义一个信号量id
	int semid = sem__init(COUNT);
	//定义key值
	key_t key;
	if ((key = ftok("/", 'm')) == -1)
	{
		perror("ftok");
		return -1;
	}

	//定义共享内存id
	int shmid;
	//创建共享内存
	if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0664)) == -1)
	{
		perror("shmget");
		return -1;
	}

	//将创建好的共享内存映射到该程序中
	char *shmaddr;
	shmaddr = shmat(shmid, NULL, 0);

	while (1)
	{
		sleep(1);
		//2、申请1号灯的资源
		P(semid, 1);
		shmaddr[2] = 'C';
		shmaddr[3] = '\0';
		int i = 0;
		while (shmaddr[i] != '\0')
		{
			printf("%c", shmaddr[i++]);
			fflush(stdout);
			sleep(1);
		}
		signal(SIGINT, signal_handler);
		//3、释放2号灯的资源
		V(semid, 2);

	}


	//取消映射
	shmdt(shmaddr);



	return 0;
}

sem.c

#include 

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) */
};

//定义设置灯的值的函数
//给semid灯集的semno的这个灯值设置为value
void init_semnum_value(int semid, int semno, int value)
{
	union semun sem;
	sem.val = value;

	//设置信号灯的值
	semctl(semid, semno, SETVAL, sem);
}

int sem__init(int count) 	//创建一个信号灯集
{
	//1、申请key值
	key_t key;
	if ((key = ftok("/", 'm')) == -1)
	{
		perror("ftok");
		return -1;
	}

	//2、创建信号量
	int semid;
	if ((semid = semget(key, count, IPC_CREAT|IPC_EXCL|0664)) == -1)
	{
		if (errno == EEXIST)  	//说明信号灯集已经存在,直接打开即可
		{
			semid = semget(key, count, IPC_CREAT|0664);
		}
		else
		{
			perror("semget");	
			return -1;
		}
		
	}
	else
	{
		//原本不存在,重新创建一个需要对其初始化
		init_semnum_value(semid, 0, 0); 		//0号灯value初始化为0
		init_semnum_value(semid, 1, 0); 		//1号灯value初始化为0
		init_semnum_value(semid, 2, 1); 		//2号灯value初始化为1
	}

	return semid;   		//将申请的信号灯集id返回

}

int P(int semid, int semnum)  			//申请资源,将semnum资源减一
{
	struct sembuf buf; 			//定义有关灯操作的结构体
	buf.sem_num = semnum; 		//表明要更改的灯的编号
	buf.sem_op = -1; 		//表明要申请资源
	buf.sem_flg = 0; 		//阻塞等待
	
	//调用op函数
	semop(semid, &buf, 1);
	return 0;
}
int V(int semid, int semnum) 			//释放资源,将semnum资源加一
{
	struct sembuf buf; 			//定义有关灯操作的结构体
	buf.sem_num = semnum; 		//表示要更改的灯的编号
	buf.sem_op = 1; 		//表明要释放资源
	buf.sem_flg = 0; 		//阻塞等待
	
	//调用op函数
	semop(semid, &buf, 1);
	return 0;

}
int sem_del(int semid) 				//删除一个信号灯集
{
	//删除信号灯集
	return semctl(semid, 0, IPC_RMID, 0);
}

sem.h

#ifndef __SEM_H__
#define __SEM_H__

int sem__init(); 	//创建一个信号灯集
int P(int semid, int semnum);  			//申请资源,将semnum资源减一
int V(int semid, int semnum); 			//释放资源,将semnum资源加一
int sem_del(int semid); 				//删除一个信号灯集



#endif /* SEM_H */

你可能感兴趣的:(算法)