进程间通信的简单体会

 

一.实现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)    结果

 进程间通信的简单体会_第1张图片

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)    结果截图,起初能正常运行,而后产生错误,如下

 进程间通信的简单体会_第2张图片

 

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)  结果截图

 

 进程间通信的简单体会_第3张图片

二.ipcs显示IPC资源

(1)  ipcs –m:查看共享内存

(2)  ipcs –a:查看所有资源

ipcrm:手动删除IPC资源

你可能感兴趣的:(进程间通信的简单体会)