多进程间通信之有名管道

有名管道  FIFO

      一个进程以读方式打开,另一个以写方式打开才能正常运行只打开一端将阻塞。

     无名管道是临时的,在完成通信后将自动消失,且只能在具有亲缘关系的进程间实现通信,有名管道FIFO有效地客服了这一个问题。有名管道是一个存在的特殊文件,可以在不同进程间通信,用户可以通过shell来创建有名管道(mknod 命令)。

    命令管道的重用操作如下所示:

 

 C++ Code 

1
2
3
4
5
6
7

 

int mkfifo(_const char *_path, _mode_t _mode)
//  mode:如0766
fd open(const char *pathname, flages)
//flages: O_RDONLY, O_WRONLY, or O_RDWR.
int read(int _fd, void *_buf, size_t _nbytes)
int write(int _fd, void *_buf, size_t _nbytes)

   下面是一个非亲缘关系进程使用有名管道通信应用实例。

 

   写进程将要发送的数据发送到有名管道,读进程从有名管道中读取发送端发送的数据,在此过程中,只使用了一个有名管道,因此,读写是单向的,即只能从写进程读进程发送数据,如果要实现双向数据传输,则需要再使用一个有名管道。

   向命名管道中发送数据的进程源代码如下所示:

 

 C++ Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

 

#include
#include
#include
#include
#include
#include
#include
#include

#define FIFO_NAME "/tmp/my_fifo"  //命名管道位置

int main(int argc, char *argv[])
{
    int pipe_fd;
    int res;
    char buffer[] = "hello world!";
    if(access(FIFO_NAME, F_OK) == -1)  //文件是否存在
    {
        res = mkfifo(FIFO_NAME, 0766);  //创建文件
        if(res != 0)
        {
            fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
            exit(EXIT_FAILURE);
        }

    }
    printf("Process %d opening FIFO O_WRONLY\n", getpid());
    pipe_fd = open(FIFO_NAME, O_WRONLY);  //打开有名管道
    printf("the file's descriptor is %d \n", pipe_fd);
    if(pipe_fd != -1)
    {
        res = write(pipe_fd, buffer, sizeof(buffer));  //写数据
        if(res == -1)
        {
            fprintf(stderr, "Write error on pipe\n");
            exit(EXIT_FAILURE);
        }
        printf("write data is %s ,%d bytes is write\n", buffer, res); 
        close(pipe_fd);  //关闭管道
    }
    else
    {
        exit(EXIT_FAILURE);
    }
    printf("Procecss %d finished\n", getpid());
    exit(EXIT_SUCCESS);

}

 

 

 

    读进程负责从有名管道中读取数据,其源代码如下所示:

 

 C++ Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

 

#include
#include
#include
#include
#include
#include
#include
#include

#define FIFO_NAME "/tmp/my_fifo"

int main(int argv, char *argc[])
{
    int pipe_fd;
    int res;
    char buffer[4096];
    int bytes_read = 0;
    memset(buffer, '\0'sizeof(buffer));
    printf("Process %d opening FIFO O_RDONLY", getpid());
    pipe_fd = open(FIFO_NAME, O_RDONLY);  //打开管道,因为创建在写进程,故执行时需要先执行写进程。
    printf("the files descriptor is %d \n", pipe_fd);
    if(pipe_fd != -1)
    {
        bytes_read = read(pipe_fd, buffer, sizeof(buffer));  //读出数据
        printf("the read data is %s \n", buffer);
        close(pipe_fd);          //关闭管道
    }
    else
        exit(EXIT_FAILURE);
    printf("Process %d finished, %d bytes read\n", getpid(), bytes_read); 
    exit(EXIT_SUCCESS);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Linux,高级程序设计)