← 返回首页
Linux高级程序设计(五十六)
发表时间:2021-12-12 00:36:17
命名管道读写规律(阻塞)

1.读写端都存在,只读不写 如果管道中有数据,则正常读取。如果管道中没有数据,则读取端阻塞等待。 实例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{

    if (mkfifo("myfifo", 0664) != 0)
    { // 出错
        if (errno != EEXIST)
        {
            perror("erro to mkfifo:");
            exit(1);
        }
    }    

    int fd;
    //O_RDWRB表示读写端都存在。
    fd = open("myfifo", O_RDWR);
    if (fd == -1)
    {
        perror("error to open:");
        exit(1);
    }

    write(fd,"hello,world!\n",strlen("hello,world!\n"));
    char buff[128]="";
    read(fd,buff,sizeof(buff));
    printf("buff=%s",buff);
    //这里会发生阻塞...
    read(fd,buff,sizeof(buff));
    printf("buff=%s",buff);

    return 0;
}

2.读写端都存在,只写不读 读写端都存在,只写不读。默认缓冲区大小是64Kb。当缓冲区写满,会发生阻塞。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if (mkfifo("myfifo", 0664) != 0)
    { // 出错
        if (errno != EEXIST)
        {
            perror("erro to mkfifo:");
            exit(1);
        }
    }    

    int fd;
    //O_RDWRB表示读写端都存在。
    fd = open("myfifo", O_RDWR);
    if (fd == -1)
    {
        perror("error to open:");
        exit(1);
    }
    int num=0;

    while(1){
        write(fd,"hello,world!\n",strlen("hello,world!\n"));
        num++;
        //缓冲区满会发生阻塞....
        printf("num=%d",num);
    }

    return 0;
}

3.在一个进程中只有读端没有写端

在一个进程中如果只有读端没有写端会在open函数阻塞。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if (mkfifo("myfifo", 0664) != 0)
    { // 出错
        if (errno != EEXIST)
        {
            perror("erro to mkfifo:");
            exit(1);
        }
    }    

    int fd;
    //O_RDONLY以只读方式打开
    fd = open("myfifo", O_RDONLY);
    if (fd == -1)
    {
        perror("error to open:");
        exit(1);
    }

    char buff[128]="";
    ssize_t bytes;
    //这句话不会输出,说明在open时已经阻塞.
    printf("--------start to read-------");

    if((bytes = read(fd,buff,sizeof(buff)))==-1){
        perror("error to read:");
        exit(1);
    }

    printf("buff=%s\n",buff);
    printf("bytes=%d\n",bytes);

    return 0;
}

4.在一个进程中只有写端没有读端

在一个进程中只有写端没有读端,也会在open函数阻塞。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if (mkfifo("myfifo", 0664) != 0)
    { // 出错
        if (errno != EEXIST)
        {
            perror("erro to mkfifo:");
            exit(1);
        }
    }    

    int fd;
    //O_RDONLY以只写方式打开
    fd = open("myfifo", O_WRONLY);
    if (fd == -1)
    {
        perror("error to open:");
        exit(1);
    }

    char buff[128]="";
    ssize_t bytes;

    //以下语句都不会打印...,说明在open函数阻塞。
    printf("------start to write---------");
    write(fd,"hello,world!\n",strlen("hello,world!\n"));
    printf("--------end of write-------");

    return 0;
}

5.一个进程只读另一个进程只写

只要保证有名管道读写端都存在,则open函数不会阻塞。将上面两个例子同时执行,不会发生阻塞。

注意:如果写端关闭,则读端会返回0,如果读端关闭,则写端产生SIGPIPE信号,写端也会立刻关闭。