zoukankan      html  css  js  c++  java
  • 简述进程间通信方式

         进程间通信方式通常有共享内存 信号量 消息队列 管道 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 ");

                   shmdt(share1);

              }

              else if(pid>0)

              {

                    char *share2=NULL;

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

                    printf("read characters from memory! ");

                    printf("%s ",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("*************** ");

                            sig_post(sig_id,3);

                    }

            }

    else if(pid)

            {

                    i=0;

                    while(++i<10)

                    {

                            sig_wait(sig_id,1);

                            printf("++++++++++++++++ ");

                            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 ");

                    return 0;

            }

     

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

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

            printf("fd2=%d ",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 ",num);

            printf("fd2=%d ",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 ",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;

        }

  • 相关阅读:
    一本通1273货币系统(方案数背包)
    背包体积循环正序和逆序的区别
    Python字典的底层原理和优缺点
    Linux各目录及每个目录的详细介绍
    openwrt 下python程序后台运行,并将打印信息保存文件
    pycharm同一目录下无法import其他文件
    python sqlite3学习笔记
    python sqlite3查询表记录
    Pycharm快捷键的使用
    Python3 Address already in use 解决方法
  • 原文地址:https://www.cnblogs.com/3ddan/p/3251979.html
Copyright © 2011-2022 走看看