6.30 作业

1.使用消息队列,完成对结构体数据的传输 1>使用消息队列,完成对结构体数据的传输

ipcsw.c

#include <myhead.h>
#define MSGSZ (sizeof(msg_t)-sizeof(long))
typedef struct{
	char name[12];//名字
	int age;//年龄
}student;//学生结构体

typedef struct {
	long msg_type;//消息类型
	student stu;//内容
}msg_t;//消息结构体

student *get_stu(student *stu)//输入学生信息
{
	printf("输入名字:");
	scanf("%s",stu->name);
	printf("输入年龄:");
	scanf("%d",&stu->age);
	return stu;
}

int main(int argc,const char *argv[])
{
	key_t key = ftok("/",3);//定义key
	if(key == -1)
	{
		perror("key error");
		return -1;
	}

	int msgid = msgget(key,IPC_CREAT|0664);	//创建队列
	if(msgid == -1)
	{
		perror("megget error");
		return -1;
	}
	
	msg_t msg;
	msg.msg_type = 10;//设置消息类型
	while(1)
	{
		printf("输入学生信息\n");
		get_stu(&msg.stu);
		if(msgsnd(msgid,&msg,MSGSZ,0))//往队列中传递消息
		{
			perror("msgsnd error");
			return -1;
		}
		if(msg.stu.age<0)//退出循环的条件
			break;
	}
	msgctl(msgid,IPC_RMID,NULL);//删除消息队列
	return 0;
}

ipcsr.c

#include <myhead.h>
#define MSGSZ (sizeof(msg_t)-sizeof(long))
typedef struct{
	char name[12];
	int age;
}student;//学生结构体

typedef struct {
	long msg_type;
	student stu;
}msg_t;//消息结构体

void put_stu(student stu)//输出学生信息
{
	printf("名字:%s\n",stu.name);
	printf("年龄:%d\n",stu.age);
}

int main(int argc,const char *argv[])
{
	key_t key = ftok("/",3);//定义key
	if(key == -1)
	{
		perror("key error");
		return -1;
	}

	int msgid = msgget(key,IPC_CREAT|0664);	//创建并打开消息队列
	if(msgid == -1)
	{
		perror("megget error");
		return -1;
	}
	
	msg_t msg;
	msg.msg_type = 10;//设置消息类型
	while(1)
	{
		if(msgrcv(msgid,&msg,MSGSZ,10,0)==-1)//从消息队列中取数据
		{
			perror("msgrcv error");
			return -1;
		}
		if(msg.stu.age<0)//判断是否结束循环
			break;
		put_stu(msg.stu);//输出学生信息
	}
	msgctl(msgid,IPC_RMID,NULL);//删除消息队列
	return 0;
}

 

2.使用信号灯集完成三个进程的同步,使用三个进程输出:ABCABCABCABC....

pr.c

#include "sem.h"
#define SHSZ 4096
int main(int argc,const char *argv[])
{
	key_t key = ftok("/",4);//定义key
	int shmid = shmget(key,SHSZ,IPC_CREAT|0666);//定义内存id
	char *shmaddr = shmat(shmid,NULL,0);//获得共享内存地址
	int semid = init_sem(4);//创建有4个灯的信号灯集
	char t;
	while(1)
	{
		scanf("%c",&t);
		if(t!='\n')//继续的判断
			break;
		p(semid,0);//有资源的输出
		printf("%c",shmaddr[0]);//输出
		fflush(stdout);
		switch(shmaddr[0])//根据输出把资源给下一个进程
		{
			case 'A':
				v(semid,2);//给B进程
				break;
			case 'B':
				v(semid,3);//给C进程
				break;
			case 'C':
				v(semid,1);//给A进程
				break;
		}
	}
	shmdt(shmaddr);//释放地址
	shmctl(shmid,IPC_RMID,NULL);//删除共享内存
	sem_del(semid);//删除共享灯集
	return 0;
}

a.c

#include "sem.h"
#define SHSZ 4096
int main(int argc,const char *argv[])
{
	key_t key = ftok("/",4);
	int shmid = shmget(key,SHSZ,IPC_CREAT|0666);
	char *shmaddr = shmat(shmid,NULL,0);
	int semid = init_sem(4);
	while(1)
	{
		p(semid,1);//使用资源
		printf("%c\n",shmaddr[0]);
		shmaddr[0] = 'A';//把a放入共享内存
		v(semid,0);//释放资源给输出
	}
	shmdt(shmaddr);
	shmctl(shmid,IPC_RMID,NULL);
	sem_del(semid);
	return 0;
}

b.c

#include "sem.h"
#define SHSZ 4096
int main(int argc,const char *argv[])
{
	key_t key = ftok("/",4);
	int shmid = shmget(key,SHSZ,IPC_CREAT|0666);
	char *shmaddr = shmat(shmid,NULL,0);
	int semid = init_sem(4);
	while(1)
	{
		p(semid,2);
		printf("%c\n",shmaddr[0]);
		shmaddr[0] = 'B';
		v(semid,0);
	}
	shmdt(shmaddr);
	shmctl(shmid,IPC_RMID,NULL);
	sem_del(semid);
	return 0;
}

c.c

#include "sem.h"
#define SHSZ 4096
int main(int argc,const char *argv[])
{
	key_t key = ftok("/",4);
	int shmid = shmget(key,SHSZ,IPC_CREAT|0666);
	char *shmaddr = shmat(shmid,NULL,0);
	int semid = init_sem(4);
	while(1)
	{
		p(semid,3);
		printf("%c\n",shmaddr[0]);
		shmaddr[0] = 'C';
		v(semid,0);
	}
	shmdt(shmaddr);
	shmctl(shmid,IPC_RMID,NULL);
	sem_del(semid);
	return 0;
}

sem.h

#ifndef __SEM_H__
#define __SEM_H__
#include <myhead.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 init_sem(int num);//创建一个信号灯集
int p(int semid,int semnum);//申请资源,资源-1
int v(int semid,int semnum);//释放资源,资源+1
int sem_del(int semid);
static int init_value(int semid,int num,int value);//初始化灯集
#endif

sem.c

#include "sem.h"
int init_sem(int num)
{
	key_t key = ftok("/",32);//获得key
	if(key==-1)
	{
		perror("key error");
		return -1;
	}
	
	if(semget(key,num,IPC_EXCL)==-1)//信号灯集存在则返回
		return semget(key,num,IPC_CREAT|0664);

	int semid = semget(key,num,IPC_CREAT|0664);//不存在则创建
	if(semid==-1)
	{
		perror("semget error");
		return -1;
	}
	init_value(semid,0,0);	//初始化赋值
	init_value(semid,1,1);	
	init_value(semid,2,0);	
	init_value(semid,3,0);	
	return semid;
}

static int init_value(int semid,int num,int value)//初始化
{
	if(semctl(semid,num,SETVAL,value)==-1)
	{
		perror("semctl error");
		return -1;
	}
	return 0;
}

int p(int semid,int semnum)
{
	struct sembuf buf = {semnum,-1,0};//申请资源
	if(semop(semid,&buf,1)==-1)
	{
		perror("p error");
		return -1;
	}
	return 0;
}

int v(int semid,int semnum)
{
	struct sembuf buf = {semnum,1,0};//释放资源
	if(semop(semid,&buf,1)==-1)
	{
		perror("v error");
		return -1;
	}
	return 0;
}

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值