linux下編程——操作系統——管道通信


相關知識:

1、有名管道

一個可以在文件系統中長期存在的、具有路徑名的文件。用系統調用mknod( )建立。它克服無名管道使用上的局限性,可讓更多的進程也能利用管道進行通信。因而其它進程可以知道它的存在,並能利用路徑名來訪問該文件。對有名管道的訪問方式與訪問其他文件一樣,需先用open( )打開。

2、無名管道

一個臨時文件。利用pipe( )建立起來的無名文件(無路徑名)。只用該系統調用所返回的文件描述符來標識該文件,故只有調用pipe( )的進程及其子孫進程才能識別此文件描述符,才能利用該文件(管道)進行通信。當這些進程不再使用此管道時,核心收回其索引結點。

3pipe文件的建立

分配磁盤和內存索引結點、為讀進程分配文件表項、為寫進程分配文件表項、分配用戶文件描述符

4、讀/寫進程互斥

內核為地址設置一個讀指針和一個寫指針,按先進先出順序讀、寫。

為使讀、寫進程互斥地訪問pipe文件,需使各進程互斥地訪問pipe文件索引結點中的直接地址項。因此,每次進程在訪問pipe文件前,都需檢查該索引文件是否已被上鎖。若是,進程便睡眠等待,否則,將其上鎖,進行讀/寫。操作結束后解鎖,並喚醒因該索引結點上鎖而睡眠的進程。

 

 

1pipe( )

 

建立一無名管道。

 

系統調用格式

 

              pipe(filedes)

 

參數定義

 

int  pipe(filedes);

 

int  filedes[2];

 

其中,filedes[1]是寫入端,filedes[0]是讀出端。

 

該函數使用頭文件如下:

 

#include <unistd.h>

 

#inlcude <signal.h>

 

#include <stdio.h>

 

   2read( )

 

  系統調用格式

 

                  read(fd,buf,nbyte)

 

  功能:從fd所指示的文件中讀出nbyte個字節的數據,並將它們送至由指針buf所指示的緩沖區中。如該文件被加鎖,等待,直到鎖打開為止。

 

  參數定義

 

                  int  read(fd,buf,nbyte);

 

                  int  fd;

 

                  char *buf;

 

                  unsigned  nbyte;

 

  3write( )

 

系統調用格式

 

                  read(fd,buf,nbyte)

 

功能:把nbyte 個字節的數據,從buf所指向的緩沖區寫到由fd所指向的文件中。如文件加鎖,暫停寫入,直至開鎖。

 

參數定義同read( )。

 

無名管道程序源碼:

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int pid1,pid2;
 
int main()
{ 
    int fd[2];
    char outpipe[100],inpipe[100];
    pipe(fd);                       /*創建一個管道*/
    while ((pid1=fork()) == -1);
    if(pid1 == 0)
    {
        lockf(fd[1],1,0);
        sprintf(outpipe,"I am a child 1 "); 
        /*把串放入數組outpipe中*/
        write(fd[1],outpipe,50);     /*向管道寫長為50字節的串*/
        sleep(1);                 /*自我阻塞5秒*/
        lockf(fd[1],0,0);
        exit(0);
    }
    else
    {
        sleep(1);//延時等待子進程1結束
        while((pid2=fork()) == -1);
        if(pid2 == 0)
        {    
            
            lockf(fd[1],1,0);           /*互斥*/
               sprintf(outpipe,"I am a child 2 ");
                write(fd[1],outpipe,50);
                sleep(1);
               lockf(fd[1],0,0);
                exit(0);
        }
        else
        {
            wait(0);              /*同步*/
             read(fd[0],inpipe,50);   /*從管道中讀長為50字節的串*/
                printf("%s\n",inpipe);
             wait(0);
             read(fd[0],inpipe,50);
             printf("%s\n",inpipe);
                exit(0);
        }
    }
}

有名管道程序源碼:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
int pid1,pid2;

int main()
{
    char *filename = "fifo";
    int res = mkfifo(filename,0666);//創建文件
    if(res < 0)
    {
        perror("mkfifo error");
        return -1;
    }

    int fd = open(filename,O_RDWR);//打開文件
    if(fd < 0)
    {
        perror("open error");
        return -2;
    }

    while((pid1=fork()) == -1);//創建子進程1
    if(pid1 == 0)
    {
        char *str1 = "I am a child 1";
        int len1 = write(fd,str1,strlen(str1));
    }
    else
    {
        sleep(1);//等待子進程1結束
        while((pid2=fork()) == -1);
        if(pid2 == 0)
        {
            char *str2 = "   I am a child 2";
            int len2 = write(fd,str2,strlen(str2));
        }
        else 
        {
            wait(0);
            wait(0);
            int len;
            char buf[128] = {0};
            len = read(fd,buf,sizeof(buf) - 1);
            printf("%s\n",buf);

        }
    }
    
    close(fd);
    unlink(filename);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM