Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121914
  • 博文数量: 41
  • 博客积分: 1695
  • 博客等级: 上尉
  • 技术积分: 430
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-21 22:50
文章分类

全部博文(41)

文章存档

2010年(1)

2007年(23)

2006年(17)

我的朋友

分类: C/C++

2007-04-26 00:40:15

/*
 * 管道通信:有名管道
 * 无名管道只能用于具有亲缘关系的进程之间,而有名管道可以在互不相关的两个进程间
 * 实现彼此通信。要注意,FIFO严格按照先进先出的规则,对管道及FIFO的读总是从开始
 * 处返回数据,对它们的写则把数据添加到末尾,不支持lseek等文件定位操作。
 *
 * 有名管道的创建使用mkfifo()。创建成功后就可以使用open、read、write这些函数了。
 * 写管道部分
 */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

/*特别注意写管道时,设置打开管道文件的格式必须为可写*/
#define FIFO_SERVER "myfifo"
#define OPENMODE (O_WRONLY | O_NONBLOCK) //对文件的写打开依赖于读打开
#define FIFOMODE (O_CREAT | O_RDWR | O_NONBLOCK | S_IRUSR | S_IWUSR)
#define UMASK 0
int main(int argc, char **argv)
{
    int fd;
    int nwrite;

    if ((mkfifo(FIFO_SERVER, UMASK | FIFOMODE) < 0) && (errno != EEXIST)) {
        perror("cannot creat fifo\n");
        exit(0);
    }
    /*打开管道文件,可写非阻塞*/
    if ((fd = open(FIFO_SERVER, OPENMODE)) < 0) {
        perror("open");
        exit(1);
    }
    /*如果没有在命令行中写入参数,那么要重新运行程序*/
    if (argc == 1) {
        printf("Please send something\n");
        exit(1);
    }
    /*向管道文件中写入数据,在这里要用strlen,如果用sizeof,则只是4个字节的指针长度*/
    if ((nwrite = write(fd, argv[1], strlen(argv[1]))) < 0) {
        if (errno == EAGAIN) {
            printf("The FIFO has not been read yet.Please try later\n");
        }
    }
    else {
        printf("write %s to FIFO\n", argv[1]);
    }
    return 0;
}

/*
 * 管道通信:有名管道
 * 无名管道只能用于具有亲缘关系的进程之间,而有名管道可以在互不相关的两个进程间
 * 实现彼此通信。要注意,FIFO严格按照先进先出的规则,对管道及FIFO的读总是从开始
 * 处返回数据,对它们的写则把数据添加到末尾,不支持lseek等文件定位操作。
 *
 * 有名管道的创建使用mkfifo()。创建成功后就可以使用open、read、write这些函数了。
 * 读管道部分
 */

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

/*在这里设置打开管道文件的mode为只读形式*/
#define FIFOMODE (O_CREAT | O_RDWR | O_NONBLOCK)
#define OPENMODE (O_RDONLY | O_NONBLOCK)
#define FIFO_SERVER "myfifo"

int main(void)
{
    char buf[100];
    int fd;
    int readnum;

    /*创建有名管道,设置为可读写,无阻塞,如果不存在则按照指定权限创建*/
    if ((mkfifo(FIFO_SERVER, FIFOMODE) < 0) && (errno != EEXIST)) {
        printf("cannot create fifoserver\n");
        exit(1);
    }
    printf("Preparing for reading bytes... ...\n");
    /*打开有名管道,并设置非阻塞标志*/
    if ((fd = open(FIFO_SERVER, OPENMODE)) < 0) {
        perror("open");
        exit(1);
    }
    while (1) {
        /*初始化缓冲区*/
        bzero(buf, sizeof(buf));
        /*读取管道数据*/
        if ((readnum = read(fd, buf, sizeof(buf))) < 0) {
            if (errno == EAGAIN) {
                printf("no data yet\n");
            }
        }
        /*如果读到数据则打印出来,如果没有数据,则忽略*/
        if (readnum != 0) {
            buf[readnum] = '\0';
            printf("read %s from FIFO_SERVER\n", buf);
        }
        sleep(1);
    }
    return 0;
}

read:
1、如果关闭了所有的写文件描述符,那么对于空管道的read将总是立刻返回0。
2、如果写文件描述符是打开的,不管是否设置了O_NONBLOCK,空管道的read都会阻塞,等待write。
3、对于非空管道的read总是立即返回

由于写依赖于读,应此并需先运行读进程!
  • 如果没有指定非阻塞标志(O_NONBLOCK),读打开将阻塞,知道有进程写打开此FIFO。类似,写打开也要阻塞到有进程读打开FIFO。
  • 如果指定非阻塞标志(O_NONBLOCK),读打开将立即返回。写打开将出错返回,因为写打开依赖读打开。在例程中指定了非阻塞标志!
 
阅读(1612) | 评论(0) | 转发(0) |
0

上一篇:系统调用

下一篇:exit与_exit的区别

给主人留下些什么吧!~~