天天看點

IPC——管道

程序間通信(IPC)

英文名IPC,因為每個程序各自有不同的使用者位址空間,任何一個程序的全局變量在另一個程序看不到,是以程序之間要交換資料必須通過核心,在核心中開辟一塊緩沖區,程序1把資料從使用者位址空間拷到核心緩沖區,程序2再從核心緩沖區把資料讀走,核心提供的這種機制稱為程序間通信。

IPC——管道

管道:

管道是Unix中最古老的程序間通信的形式,是一種最基本的IPC機制。

我們把從一個程序連接配接到另一個程序的資料流稱為一個“管道”。

特點:

(1)隻能用于有公共祖先的程序之間通信。

(2)管道提供流式服務

(3)生命周期随程序

(4)核心會對管道進行同步與互斥

(5)管道是半雙工的,需要雙方通信時,須建立兩個管道。

匿名管道

#include<unistd.h>
int pipe(int  fd[]);
//成功傳回0,失敗傳回錯誤代碼
           

fd[0]為讀而打開,fd[1]為寫而打開

fd[1]的輸出是fd[0]的輸入。

單個程序中的管道幾乎沒有任何用處。管道隻能在具有公共祖先的兩個程序之間使用。通常,一個管道由一個程序建立,在程序調用fork之後,這個管道就能在父程序和子程序之間使用了。

父程序調用pipe開辟管道,得到兩個檔案描述符指向管道的兩端,父程序調用fork建立了子程序,子程序也有兩個檔案描述符指向同一管道。

因為管道是單向通信的,是以父程序關閉寫端,子程序關閉讀端。子程序可以往管道裡寫,父程序可以在管道裡讀。

IPC——管道

代碼實作:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
    //(1)程序建立管道
    int fds[] = {,};
    int ret = pipe(fds);
    if(ret < )
    {
       perror("pipe");
       return ;
    }
    //(2)建立子程序
    pid_t  id = fork();
    //父程序關閉寫端,子程序關閉讀端
    if( id == )//子程序——>寫
    {
      close(fds[]);
      char* msg = "hello father,I am your child";
      while()
      {
        write(fds[],msg,strlen(msg));
        sleep();
      }
    }
    else//父程序——>讀
    {
      char buf[];
      close(fds[]);
      while()
      {
        ssize_t s = read(fds[],buf,sizeof(buf)-);
        if(s > )
        {
            buf[s] = ;
            printf("%s\n",buf);
        } 
    }
      }
      return ;
}  
[[email protected] ~]$ ./a.out
hello father,I am your child
hello father,I am your child
hello father,I am your child
hello father,I am your child
           

命名管道

匿名管道隻能用于有血緣關系的程序。命名管道(FIFO)的提出就突破了管道的限制,它可以以不同的方式方法調用(可以跨平台,跨語言,跨權限),隻要知道命名管道的名字,發送到命名管道的資訊可以被一切擁有指定授權的程式讀取。

建立:

//(1)指令行上建立
$ mkfifo filename
//從程式裡建立
int mkfifo(const char *filename,mode_t mode);//成功傳回0,失敗傳回-1
           

建立命名管道

int main(int argc, char *argv[])
{
    mkfifo("p2",);
    return ;
}
           
#include<stdio.h>
#include<sys/stat.h>

int main()
{
   int ret = mkfifo("./myfifo",);
   if(ret < )
   {
      perror("mkfifo");
      return ;
   }
   printf("mkfifo ok\n");
   return ;
}
[a@localhost ~]$ gcc fifo.c
[a@localhost ~]$ ./a.out
mkfifo ok
           

用命名管道實作server&client通信

server.c

IPC——管道

client.c

IPC——管道

makefile

IPC——管道

結果:

IPC——管道

繼續閱讀