一.实现pipe/msgqueue/sems/shm相关代码
1. 实现pipe,从键盘读取数据写入管道,读取数据,写到屏幕
(1) 代码
#include
#include
#include
#include
intmain()
{
int fds[2];
char buf[100];
int len;
if(pipe(fds)==-1)
perror("make pipe"),exit(1);
while(fgets(buf,100,stdin)){
len=strlen(buf);
if(write(fds[1],buf,len)!=len){
perror("write to pipe");
break;
}
memset(buf,0x00,sizeof(buf));
if((len=read(fds[0],buf,100))==-1){
perror("read from pipe");
break;
}
if(write(1,buf,len)!=len){
perror("write to stdout");
break;
}
}
}
(2) 结果
2. 实现msgqueue
(1) comm.h
#include
#include
#include
#include
# definePATHNAME"."
# definePROJ_ID 0x6666
# defineSEVER_TYPE 1
# defineCLIENT_TYPE 2
structmsgbuf{
long mtype;
char mtext[1024];
};
intcreatMsgQueue();
intgetMsgQueue();
intdestroyMsgQueue(int msgid);
intsendMsg(int msgid,int who,char *msg);
intrecvMsg(int msgid,int recvType,char out[]);
# endif
(2) comm.c
#include"comm.h"
staticint commMsgQueue(int flags)
{
key_t _key=ftok(PATHNAME,PROJ_ID);
if(_key<0){
perror("ftok");
return -1;
}
//intmsgid=msgget(_key,IPC_CREAT|IPC_EXCL|0666);
int msgid=msgget(_key,flags);
if(msgid<0){
perror("msgget");
}
return msgid;
}
intcreateMsgQueue()
{
returncommMsgQueue(IPC_CREAT|IPC_EXCL|0666);
}
intgetMsgQueue()
{
return commMsgQueue(IPC_CREAT);
}
intdestroyMsgQueue(int msgid)
{
if(msgctl(msgid,IPC_RMID,NULL)<0){
perror("msgctl");
return -1;
}
return 0;
}
intsendMsg(int msgid,int who,char *msg)
{
struct msgbuf buf;
buf.mtype=who;
strcpy(buf.mtext,msg);
if(msgsnd(msgid,(void*)&buf,sizeof(buf.mtext),0)<0){
perror("msgsnd");
return -1;
}
return 0;
}
intrecvMsg(int msgid,int recvType,char out[])
{
struct msgbuf buf;
if(msgrcv(msgid,(void*)&buf,sizeof(buf.mtext),recvType,0)<0){
perror("msgrcv");
return -1;
}
strcpy(out,buf.mtext);
return 0;
}
(3) server.c
# include"comm.h"
intmain()
{
int msgid=createMsgQueue();
char buf[1024];
while(1){
buf[0]=0;
recvMsg(msgid,CLIENT_TYPE,buf);
printf("client# %s\n",buf);
printf("please Enter# ");
fflush(stdout);
ssize_t s=read(0,buf,sizeof(buf));
if(s>0){
buf[s-1]=0;
sendMsg(msgid,SERVER_TYPE,buf);
printf("send done,waitrecv...\n");
}
}
destroyMsgQueue(msgid);
return 0;
}
//法2
intmsgid=createQueue();
printf("msgid:%d\n",msgid);
while(1){
char buf[2048]={0};
intret=ReadQueue(msgid,CLIENT_TYPE,buf,sizeof(buf)-1);
if(ret<0){
printf("ReadQueue error!\n");
continue;
}
printf("client:%s\n",buf);
if(ret<0){
printf("WriteQueue error!\n");
continue;
ret=WriteQueue(msgid,SERVER_TYPE,buf,strlen(buf));
}
}
(4) client.c
#include"comm.h"
intmain()
{
int msgid=getMsgQueue();
char buf[1024];
while(1){
buf[0]=0;
printf("please Enter# ");
fflush(stdout);
//ssize_tRead_size=read(0,buf,sizeof(buf)-1);
//if(size_t<0)
//perror("read");
//if(size_t==0){
//printf("Readdone");
//break;
//}
//buf[Read_size]='\0';
//intret=WriteQueue(msgid,CLIENT_TYPE,buf,strlen(buf));
//if(ret<0){
//perror("Write");
//}
//ints=ReadQueue(msgid,CLIENT_TYPE,buf,strlen(buf));
//if(s<0){
//perror("Read");
//}
ssize_t s=read(0,buf,sizeof(buf));
if(s>0){
buf[s-1]=0;
sendMsg(msgid,CLIENT_TYPE,buf);
printf("send done,waitrecv...\n");
}
recvMsg(msgid,SERVER_TYPE,buf);
printf("server# %s\n",buf);
}
return 0;
}
3. 实现sems
(1) comm.h
# define__COMM_H__
# include
#include
#include
#include
# definePATHNAME "."
# definePROJ_ID 0x6666
unionsemun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *_buf;
};
intcreateSemSet(int nums);
intinitSem(int semid,int nums,int initVal);
intgetSemSet(int nums);
int p(intsemid,int who);
int v(intsemid,int who);
intdestroySemSet(int semid);
#endif
(2) comm.c
#include"comm.h"
staticint commSemSet(int nums,int flags)
{
key_t key=ftok(PATHNAME,PROJ_ID);
if(key<0){
perror("ftok");
return -1;
}
int semid=semget(key,nums,flags);
if(semid<0){
perror("semget");
return -2;
}
return semid;
}
intcreateSemSet(int nums)
{
return commSemSet(nums,IPC_CREAT|IPC_EXCL|0666);
}
intgetSemSet(int nums)
{
return commSemSet(nums,IPC_CREAT);
}
intinitSem(int semid,int nums,int initVal)
{
union semun _un;
_un.val=initVal;
if(semctl(semid,nums,SETVAL,_un)<0){
perror("semctl");
return -1;
}
return 0;
}
staticint commPV(int semid,int who,int op)
{
struct sembuf _sf;
_sf.sem_num=who;
_sf.sem_op=op;
_sf.sem_flg=0;
if(semop(semid,&_sf,1)<0){
perror("semop");
return -1;
}
return 0;
}
int p(intsemid,int who)
{
return commPV(semid,who,-1);
}
int v(intsemid,int who)
{
return commPV(semid,who,1);
}
intdestroySemSet(int semid)
{
if(semctl(semid,0,IPC_RMID)<0){
perror("semctl");
return -1;
}
}
(3) test.c
#include"comm.h"
intmain()
{
int semid=createSemSet(1);
initSem(semid,0,1);
pid_t id=fork();
if(id==0){
int _semid=getSemSet(0);
while(1){
p(_semid,0);
printf("A");
fflush(stdout);
usleep(123456);
printf("A");
fflush(stdout);
usleep(123456);
v(_semid,0);
}
}
else{
while(1){
p(semid,0);
printf("B");
fflush(stdout);
usleep(223456);
printf("B");
fflush(stdout);
usleep(121456);
v(semid,0);
}
wait(NULL);
}
destroySemSet(semid);
return 0;
}
(4) 结果截图,起初能正常运行,而后产生错误,如下
4. 实现shm
(1) Comm.h
# ifndef __COMM_H__
# define__COMM_H__
#include
#include
#include
#include
# definePATHNAME "."
# define PROJ_ID0x6666
intcreateShm(int size);
intdestroyShm(int shmid);
int getShm(intsize);
# endif
(2) comm.c
#include"comm.h"
staticint commShm(int size,int flags)
{
key_t key=ftok(PATHNAME,PROJ_ID);
if(key<0){
perror("ftok");
return -1;
}
int shmid=0;
if(shmid=shmget(key,size,flags))<0){
perror("shmget");
return -2'
}
return shmid;
}
intdestroyShm(int shmid){
if(shmctl(shmid,IPC_RMID,NULL)<0){
perror("shmctl");
return -1;
}
return 0;
}
int createShm(int size)
{
returncommShm(size,IPC_CREAT|IPC_EXCL|0666);
}
intgetShm(int size)
{
return commShm(size,IPC_CREAT);
}
(3) server.c
# include"comm.h"
intmain()
{
int shmid=createShm(4096);
char *addr=shmat(shmid,NULL,o);
sleep(2);
int i=0;
while(i++<26){
printf("client# %s\n",addr);
sleep(1);
}
shmdt(addr);
sleep(2);
destroyShm(shmid);
return 0;
}
(4) client.c
#include"comm.h"
intmain()
{
int shmid=getShm(4096);
sleep(1);
char *addr=shmat(shmid,NULL,0);
sleep(2);
int i=0;
while(i<26){
addr[i]='A'+i;
i++;
addr[i]=0;
sleep(1);
}
shmdt(addr);
sleep(2);
return 0;
}
(5) 结果截图
二.ipcs显示IPC资源
(1) ipcs –m:查看共享内存
(2) ipcs –a:查看所有资源
ipcrm:手动删除IPC资源