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);//删除灯集
}