中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

實現進程間通信:匿名管道和命名管道

發布時間:2020-08-18 09:52:10 來源:網絡 閱讀:2564 作者:小止1995 欄目:編程語言

通信:因為進程有強大獨立性,當想把自己數據交給另一個進程,需要通信。

通信本質:讓不同進程看到相同資源。

實現進程間通信:匿名管道和命名管道

  1. 匿名管道:管道:通過某種機制傳遞資源(數據),匿名管道只適用于有血緣關系的進程,一般用于父,子進程通信。

    a.創建管道

    b.創建子進程

    c.父,子進程關閉自己不需要的文件描述符

    注意:匿名管道提供單向通信,父讀子寫或父寫子讀,若要實現雙向通信,可再創建一個管道。

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
    int _pipefd[2]={-1,-1};
    int ret=pipe(_pipefd);
    if(ret==-1)
    {
        perror("pipe");
        return 2;
    }
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return 2;
    }
    else if(id==0)
     {
        close(_pipefd[0]);
        char buf[]="hello world";
        int count=5;
        while(count--)
        {
            write(_pipefd[1],buf,strlen(buf));
            sleep(1);
        }
    }
    else
     {  
       close(_pipefd[1]);
       char buf[1024]={0};
       while(1)
        {
          memset(buf,'\0',sizeof(buf));
          ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
          if(_size>0)
          {
               buf[_size]='\0';
               printf("buf:%s\n",buf);
          }    
        }
    }
    return 0; 
}

運行結果:實現進程間通信:匿名管道和命名管道

使用管道需注意以下四種情況:

1.如果所有指向管道寫端的文件描述符都關閉了仍然有進程從管道的讀端讀數據,那么管道中剩余的數據都被讀取后,再次read會返回0,就像讀到文件末尾一樣。

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5 #include<stdlib.h>
  6 int main()
  7 {
  8     int _pipefd[2]={-1,-1};
  9     int ret=pipe(_pipefd);
 10     if(ret==-1)
 11     {
 12         perror("pipe");
 13         return 2;
 14     }
 15
 16     pid_t id=fork();
 17     if(id<0)
 18     {
 19         perror("fork");
 20         return 2;
 21     }
 22     else if(id==0)
 23      {
 24         close(_pipefd[0]);
 25         char buf[]="hello world";
 26         int count=5;
 27         int i=0;
 28         while(count--)
 29         {
 30             if(i==3)
 31             {
 32                 printf("I want sleep\n");
 33                 break;
 34             }
 35             write(_pipefd[1],buf,strlen(buf));
 36             sleep(1);
 37             i++;
 38         }
 39         close(_pipefd[0]);
 40     }
 41     else
 42     {
 43         close(_pipefd[1]);
 44         char buf[1024]={0};
 46         while(1)
 47         {
 48             memset(buf,'\0',sizeof(buf));
 49             ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
 50             if(_size>0)
 51             {
 52                   buf[_size]='\0';
 53                 printf("buf:%s\n",buf);
 54             }
 55         }
 56     }
 57     return 0;
 58 }

運行結果:實現進程間通信:匿名管道和命名管道

2.如果有指向管道寫端的文件描述符沒關閉,持有管道寫端的進程也沒有向管道中寫數據,這時有進程從管道讀端讀數據,那么管道中剩余的數據都被讀取后,再次read會阻塞,直到管道中有數據可讀了才讀取數據并返回。

1 #include<stdio.h>
  2 #include<sys/wait.h>
  3 #include<string.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<stdlib.h>
  7 int main()
  8 {
  9     int _pipefd[2]={-1,-1};
 10     int ret=pipe(_pipefd);
 11     if(ret==-1)
 12     {
 13         perror("pipe");
 14         return 2;
 15     }
 16 
 17     pid_t id=fork();
 18     if(id<0)
 19     {
 20         perror("fork");
 21         return 2;
 22     }
 23     else if(id==0)
 24     {
 25         close(_pipefd[0]);
 26         char buf[]="hello world";
 27         int count=5;
 28         int i=0;
 29         while(count--)
 30         {
 31              if(i==3)
 32              {
 33                   printf("I want sleep\n");
 34                   sleep(10);
 35              }
 36              write(_pipefd[1],buf,strlen(buf));
 37              sleep(1);
 38              i++;
 39         }
 40         close(_pipefd[0]);
 41     }
 42     else
 43     {
 44         close(_pipefd[1]);
 45         char buf[1024]={0};
 46         while(1)
 47         {
 48             memset(buf,'\0',sizeof(buf));
 49             ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
 50             if(_size>0)
 51             {
 52                 buf[_size]='\0';
 53                 printf("buf:%s\n",buf);
 54             }
 55         }
 56     }
 57     return 0;
 58 }

運行結果:

實現進程間通信:匿名管道和命名管道

實現進程間通信:匿名管道和命名管道

3.如果所有指向管道讀端的文件描述符都關閉了,這時有進程向管道的寫端write,那么該進程會收到信號SIGPIPE,通常會導致進程異常終止

  1 #include<stdio.h>
  2 #include<sys/wait.h>
  3 #include<string.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<stdlib.h>
  7 int main()
  8 {
  9     int _pipefd[2]={-1,-1};
 10     int ret=pipe(_pipefd);
 11     if(ret==-1)
 12     {
 13         perror("pipe");
 14         return 2;
 15     }
 16 
 17     pid_t id=fork();
 18     if(id<0)
 19     {
 20         perror("fork");
 21         return 2;
 22     }
 23     else if(id==0)
 24     {
 25         close(_pipefd[0]);
 26         char buf[]="hello world";
 27         int count=5;
 28         while(count--)
 29         {
 30              write(_pipefd[1],buf,strlen(buf));
 31              sleep(1);
 32         }
 33         close(_pipefd[0]);
 34     }
 35     else
 36     {
 37         close(_pipefd[1]);
 38         char buf[1024]={0};
 39         int i=5;
 40         while(i--)
 41         {
 42             if(i==3)
 43             {
 44                 close(_pipefd[0]);
 45             }
 46             memset(buf,'\0',sizeof(buf));
 47             ssize_t _size=read(_pipefd[0],buf,sizeof(buf)-1);
 48             if(_size>0)
 49             {
 50                 buf[_size]='\0';
 51                 printf("buf:%s\n",buf);
 52             }
 53         }
 54         int status=0;
 55         pid_t _pid=waitpid(id,&status,0);
 56         printf("waitpid: %d,return status:%d\n",id,status&0xff);
 57     }
 58     //printf("%d ,%d \n",_pipefd[0],_pipefd[1]);
 59     return 0;
 60 }

運行結果:

實現進程間通信:匿名管道和命名管道

實現進程間通信:匿名管道和命名管道


4.如果有指向管道讀端的文件描述符沒關閉,持有管道讀端的進程也沒有從管道中讀數據,這時有進程向管道寫端寫數據,那么在管道被寫滿時再次write會阻塞,直到管道中有空位置了才寫入數據并返回。 

  1 #include<stdio.h>
  2 #include<sys/wait.h>
  3 #include<string.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<stdlib.h>
  7 int main()
  8 {
  9     int _pipefd[2]={-1,-1};
 10     int ret=pipe(_pipefd);
 11     if(ret==-1)
 12     {
 13         perror("pipe");
 14         return 2;
 15     }
 16 
 17     pid_t id=fork();
 18     if(id<0)
 19     {
 20         perror("fork");
 21         return 2;
 22     }
 23     else if(id==0)
 24     {
 25         close(_pipefd[0]);
 26         char buf[]="hello world";
 27         int count=5;
 28         while(count--)
 29         {
 30              write(_pipefd[1],buf,strlen(buf));
 31              sleep(1);
 32         }
 33         close(_pipefd[0]);
 34     }
 35     else
 36     {
 37         close(_pipefd[1]);
 38         int status=0;
 39         pid_t wait=waitpid(id,&status,0);
 40         if(wait==id)
 41            printf("wait:%d,status:%d\n",wait,status);
 42     }
 43     return 0;
 44 }

總結匿名管道特點:

  1. 單向通信,適用于有血緣關系的進程通信。

  2. 管道提供流式服務(數據按序,不規定一次讀多少)

  3. 管道內部有保證數據讀完(完整性)。

  4. 進程間同步

通過路徑看到共同資源

  1. 在shell下交互的建立

  2. 調用函數

//client:
  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/types.h>
  4 #include<sys/stat.h>
  5 #include<stdlib.h>
  6 #include<string.h>
  7 #include<fcntl.h>
  8 int main()
  9 {
 10     umask(0);
 11     int fd=mkfifo("./.tmp",S_IFIFO|0666);
 12     if(fd<0)
 13     {
 14         perror("mkfifo");
 15         exit(1);
 16     }
 17     int _fd=open("./.tmp",O_WRONLY);
 18     if(_fd<0)
 19     {
 20         perror("mkfifo");
 21         exit(1);
 22     }
 23     while(1)
 24     {
 25     char buf[1024];
 26     fflush(stdout);
 27     memset(buf,'\0',sizeof(buf));
 28     printf("client:");
 29     size_t size=read(0,buf,sizeof(buf)-1);
 30     buf[size]='\0';
 31     write(_fd,buf,strlen(buf));
 32     }
 33     return 0;
 34 }
//server:
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<sys/types.h>
  4 #include<sys/stat.h>
  5 #include<fcntl.h>
  6 #include<unistd.h>
  7 #include<stdlib.h>
  8 int main()
  9 {
 10     int _fd=open("./.tmp",O_RDONLY);
 11     if(_fd<0)
 12     {
 13         perror("open");
 14         exit(1);
 15     }
 16     char buf[1024];
 17     while(1)
 18     {
 19         memset(buf,'\0',sizeof(buf));
 20         ssize_t _size=read(_fd,buf,sizeof(buf)-1);
 21         if(_size>0)
 22         {
 23             buf[_size]='\0';
 24             printf("server:%s",buf);
 25         }
 26         else
 27         {
 28             printf("read error\n");
 29             break;
 30         }
 31     }
 32     close(_fd);
 33     return 0;
 34 }
//Makefile編寫:
 .PHONY:all
  2 all:client server
  3
  4 client:client.c
  5     gcc -o $@ $^
  6 server:server.c
  7     gcc -o $@ $^
  8 .PHONY:clean
  9 clean:
 10     rm -f client server .tmp

結果驗證:打開兩個終端,不同進程可以通信。

實現進程間通信:匿名管道和命名管道

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

正定县| 萨迦县| 永清县| 开阳县| 仙居县| 小金县| 浮山县| 彭泽县| 寿宁县| 柳江县| 绿春县| 洱源县| 通海县| 疏附县| 华坪县| 广安市| 汨罗市| 江陵县| 漳州市| 松江区| 垣曲县| 丰台区| 昭苏县| 安宁市| 汉川市| 浦江县| 读书| 盈江县| 中江县| 赤壁市| 黑山县| 馆陶县| 六枝特区| 沂水县| 阜康市| 龙里县| 南靖县| 达尔| 镇平县| 临沧市| 安庆市|