Linux之进程通信

一、共享内存:

系统调用:shmget();当shmget()创建了一块新的共享内存后,返回一个可以用于引用该共享内存的shmid_ds数据结构的标识符。 

      原型:int shmget(key_t key,int size,int shmflg);

  返回值:如果成功,返回共享内存段标识符。

                 如果失败,则返回-1

系统调用:shmat();将共享内存区域映射到自己进程中去。

      原型:int shmat(int shmid,char *shmadddr,int shmflg);

   返回值:如果成功,则返回共享内存段连接到进程中的地址。

        如果失败,则返回-1。

系统调用:shmdt();当一个进程不再需要共享的内存段时,它将会把内存段从其他地址空间中脱离。

      原型:int shmdt(char *shmaddr);

   返回值:如果失败,则返回-1

实例代码:shmadd.c

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdio.h>

#include <stdlib.h>

#define BUFSZ 2048

int main()

{

   int shmid;

   char *shmadd;

   if((shmid=shmget(IPC_PRIVATE,BUFSZ,0666))<0)

{

   perror("shmget");

   exit(1);

}

else printf("created shared-memory:%d\n",shmid);

system("ipcs -m");/*ipcs 命令往标准输出写入一些关于活动进程间通信设施的信息。*/

if((shmadd=shmat(shmid,0,0))<(char *)0)

{

    perror("shmat");

    exit(1);

 }

else printf("attached shared-memory\n");

system("ipcs -m");

if((shmdt(shmadd))<0)

{

     perror("shmdt");

     exit(1);

 }

else printf("deleted shared-memory\n");

system("ipcs -m");

exit(0);

}

二、消息队列:

消息队列就是消息的一个链表,它允许一个或多个进程向它写消息,一个或多个进程从中读消息。具有一定的FIFO的特性,但是可实现消息的随即查询。这些消息存在内核中,由“队列ID”来标识。

 消息队列的实现包括创建和打开队列、添加消息、读取消息和控制消息队列这四种操作。

int msgget(key_t key,int flag):创建和打开队列,其消息数量受系统限制。

int msgsnd(int msqid,struct msgbuf *msgp,size_t msgsz,int flag):添加消息,将消息添加到消息队列尾部。

int msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long msgtyp,int flag):读取消息,从消息队列中取走消息。

int msgctl(int msqid,int cmd,struct msqid_ds *buf):控制消息队列。

实例代码msg.c

#include <sys/types.h>
	#include <sys/ipc.h>
	#include <sys/msg.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>
	#include <string.h>
	#define BUFSZ 512
	struct message
	{
	  long msg_type;
	  char msg_text[BUFSZ];
	};
	int main()
	{
	  int qid;
	  key_t key;
	  int len;
	  struct message sndmsg,rcvmsg;
	  
	  if((key=ftok(".","a"))==-1)
	  {   perroe("ftok");
	      exit(1);
	   }
	   if((qid=msgget(key,IPC_CREAT|0666))==-1)
	   {
	      perror("msgget");
	      exit(1);
	    }
	   printf("opened queue %d\n",qid);
	   puts("Please enter the message to queue:");
	   if((fgets((&sndmsg)->msg_text,BUFSZ,stdin))==NULL)
	   {
	     puts("no message");
	     exit(1);
	    }
	    sndmsg.msg_type=getpid();
	    len=strlen(sndmsg.msg_text);
	    if((msgsnd(qid,&sndmsg,len,0))<0)
	     {
	       perror("message posted");
	       exit(1);
	      }
	      if((msgrcv(qid,&rcvmsg,BUFSZ,0,0)<0)
	      {
	        perror("msgrcv");
	        exit(1);
	       }
	       printf("message is :%s\n",(&rcvmsg)->msg_text);
	       if((msgctl(qid,IPC_RMID,NULL))<0)
	       {
	         perror("msgctl");
	         exit(1);
	        }
	        exit(0);
	 }

三、管道

创建一个简单的管道,可以使用系统调用pipe()。他接受一个参数,也就是一个包括两个整数的数组。如果系统调用成功,此数组将包括管道使用的两个文件描述符。创建一个管道之后,一般情况下进程将产生一个新的进程。

系统调用:pipe();

       原型:int pipe(int fd[2]);


注意:fd[0]用于读取管道,fd[1]用于写入管道。

           一个管道是半双工的。

管道实例代码:

#include <unistd.h>

#include <sys/types.h>

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

int main()

{

   int pipe_fd[2];/*管道描述符*/

   pid_t pid;     /*定义进程ID*/

    char buf_r[100];/*读的字符串*/

    char *p_wbuf;   /*写的字符串的指针*/

    int r_num;      

    memset(buf_r,0,sizeof(buf_r));/*将buf_r字符数组中的数据全都清为0*/

   if(pipe(pipe_fd)<0)

   {

      printf("pipe create error\n");

      return -1;

    }

    /*父进程写,子进程读*/

    if((pid=fork())==0)  /*在fork()创建的子进程当中*/ 

    {

      printf("\n");

      close(pipe_fd[1]);/*写管道描述符关闭*/

      sleep(2);         /*休眠2秒*/

      if((r_num=read(pipe_fd[0],buf_r,100))>0)  /*在pipe_fd[0]的管道描述符中读100个字节放入到buf_r中*/

      {

        printf("%d numbers read from the pipe is %s\n",r_num,buf_r);

       }

      close(pipe_fd[0]);/*写管道描述符关闭*/

      exit(0);          /*退出*/

      }

      else if(pid>0)

      {

        close(pipe_fd[0]);/*读管道描述符关闭*/

        if(write(pipe_fd[1],"Hello",5)!=-1)

         printf("parent write1 success!\n");

        if(write(pipe_fd[1],"Pipe",5)!=-1)

         printf("parent write2 success!\n");

        close(pipe_fd[1];

        sleep(3);

        waitpid(pid,NULL,0);

        exit(0);

      }

   }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值