简述进程间通信方式

     进程间通信方式通常有共享内存 信号量 消息队列 管道 FIFO Socket等几种。  

     共享内存的模型,它是最有效率的进程间通信方式
 
     进程间信号量是进程间同步主要方式,信号量操作为负的时候,进程阻塞。直到信号量为正   
     内存映射是一种特殊的共享内存方式,只是本质上是对文件的操作
     管道是亲戚进程间通信的常用方式,常用于输入输出重定向   
     Fifo也成为命名管道,可用于无关联进程之间
     Socket是唯一一个不同主机间进程通信的方式
     下面简单介绍一下他们的特点与功能
      

              共享内存(分配 绑定 脱离 释放)

1:效率高,特别是大数据量通信

2:各进程需要协调共同的键值,需要提供额外机制防止竞争条件

3:异步通信

4:和信号量一同使用

                   内存映射(多进程共享文件进行通信的机制)

                   1:分配内存

                   2:读入文件内容至内存

                   3:内存的内容回写到文件

              信号量

1:线程信号量:同步多线程环境的计数器。

2:进程间同步的信号量: System V信号量,操作和sharedmemory类似。

              消息队列

1打开或创建消息队列

2读写操作

3获得或设置队列属性

              管道

1:单向信息的传递设备

2:用于进程的线程之间或者是父子进程之间通信

3:自动同步进程(管道的容量是有限的当管道写满的时候,写入端自动阻塞管道容量4096字节)

 

              FIFO

1:在文件系统中是一个有名字的管道

2:任何进程都可以打开

3:进程间无需关联

 

              SocketSocket

1:是一种双向通信设备

2:同一主机不同进程间通信

3:不同主机间的通信

    以下是一些程序,帮助大家理解

 共享内存

#include"stdio.h"

      #include"sys/shm.h"

      #include"string.h"

      #include"fcntl.h"

      #include"sys/stat.h"

      int main()

      {

          pid_t pid;

          int share_id;

          share_id=shmget(IPC_PRIVATE,getpagesize(),IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR );

          pid=fork();

          if(pid==0)

          {

               char *share1=NULL;

               share1=(char*) shmat (share_id, 0,0);

               memset(share1,0,getpagesize());

               strcpy(share1,"hello,everyone\n");

               shmdt(share1);

          }

          else if(pid>0)

          {

                char *share2=NULL;

                share2=(char*) shmat(share_id,0,0);

                printf("read characters from memory!\n");

                printf("%s\n",share2);

                shmdt(share2);

                shmctl(share_id,IPC_RMID,0);

          }

           return 1;

      }

信号量

     #include <sys/types.h>

     #include <sys/ipc.h>

     #include <sys/sem.h>

     #include<stdio.h>

     #include<sys/stat.h>

     #include<fcntl.h>

     #include<unistd.h>

     #define MAX 3

     union semun

    {

        int val;

        struct semid_ds *buf;

        unsigned short int *array;

        struct seminfo *_buf;

    };

    int sig_alloc(key_t key, int sem_flags)

    {

        return semget (key, MAX, sem_flags);

    }

 

    int sig_destory (int semid,int numth)

    {

        union semun ignored_argument;

        return semctl (semid, numth, IPC_RMID,ignored_argument);

    }

/*

        parray is a set of initialized value

*/

    int sig_init (int semid,int *parray)

   {

        union semun argument;

        int i=0;

        for(i=0;i<MAX;i++)

        {

        //      values[i] = *(parray+i);  

                argument.array = parray;

                semctl (semid, i, SETALL, argument);

        }

   }

   int sig_wait(int semid,int numth)

   {

        struct sembuf operations[MAX];

        operations[numth-1].sem_num = numth-1;

        operations[numth-1].sem_op = -1;

        operations[numth-1].sem_flg = SEM_UNDO;

        return semop(semid,operations,1);

   }

 

 int sig_post(int semid,int numth)

   {

        struct sembuf operations[MAX];

        operations[numth-1].sem_num = numth-1;

        operations[numth-1].sem_op = 1;

        operations[numth-1].sem_flg = SEM_UNDO;

        return semop(semid,operations,1);

   }

int main()

   {

        pid_t pid;

        int sig_id,i=0;

        int sig_val[MAX]={1,0,0};

        sig_id=sig_alloc(0,IPC_CREAT);

        sig_init(sig_id,sig_val);

        pid=fork();

        if(pid==0)

        {

                while(++i<10)

                {

                        sig_wait(sig_id,3);

                        printf("*************** \n");

                        sig_post(sig_id,3);

                }

        }

else if(pid)

        {

                i=0;

                while(++i<10)

                {

                        sig_wait(sig_id,1);

                        printf("++++++++++++++++\n");

                        sig_post(sig_id,1);

                }

 

        }

        return 1;

    }

内存映射

#include <sys/mman.h>

#include <sys/types.h>

#include<stdio.h>

#include<string.h>

#include<sys/stat.h>

#include<stdlib.h>

#include<fcntl.h>

#include<unistd.h>

#define FILE_LENGTH 100

int main(int argc,char **argv)

{

        int fd1,fd2;

        char *pfile=NULL;

        char *load=NULL;

        int num;

        if(argc<3)

        {

                printf("please input more file\n");

                return 0;

        }

 

        fd1=open(argv[1],O_RDONLY);

        fd2=open(argv[2],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);

        printf("fd2=%d\n",fd2);

 

        //fd2=open(argv[2],O_WRONLY);

        lseek (fd2, FILE_LENGTH+1, SEEK_SET);

        write (fd2, "", 1);

        lseek (fd2, 0, SEEK_SET);

        printf("num=%d\n",num);

        printf("fd2=%d\n",fd2);

 

        pfile=(char*)mmap(0,FILE_LENGTH,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd2,0);

        read(fd1,pfile,FILE_LENGTH);

        write(fd2,pfile,FILE_LENGTH);

        close(fd2);

        printf("pfile=%d\n",pfile);

        munmap(pfile,FILE_LENGTH);

        close(fd1);

        return 1;

}

  管道

     #include <sys/mman.h>

     #include <sys/types.h>

     #include<stdio.h>

     #include<string.h>

     #include<sys/stat.h>

     #include<stdlib.h>

     #include<fcntl.h>

     #include<unistd.h>

   int main ()

   {

    int fds[2];

    pid_t pid;

    pipe (fds);

    pid = fork ();

    if (pid == (pid_t) 0)

    {

      char str[10000];

      sleep(1);

      close(fds[1]);

      read(fds[0],str,10000);

      printf("%s",str);

      close(fds[0]);

    }

    else if(pid>0)

    {

        FILE*fp;

        char a[80];

        close(fds[0]);

        fp=(fopen("copy1.c","r"));

        if(fp==NULL)

        {

           printf("can not open!!");

           exit(0);

        }

        else

        {

        while(1)

        {

          if(fread(a,80,1,fp)==0) break;

          write(fds[1],a,sizeof(a));

        }

        }

          wait();

          close(fds[1]);

          fclose(fp);

          return 0;

    }

posted on 2013-08-11 21:51  寻找心的巨人  阅读(414)  评论(0编辑  收藏  举报

导航