多线程/多进程写FIFO为原子操作(一次写小于PIPE_BUF内容)

来源:互联网 发布:中经网产业数据库 编辑:程序博客网 时间:2024/05/29 02:29
#include <stdio.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <limits.h>#define WRITENUM        4typedef struct writeattr        writeattr;struct writeattr{        int     id;        int     fd;};int     run_flag;writeattr wattr[WRITENUM];void *readfifo(void *arg){        int     n, num=0;        int     fd = (int)arg;        char    buf[PIPE_BUF];        while(run_flag){                n = read(fd, buf, PIPE_BUF);                if(n < 0)                        continue;                if(n != PIPE_BUF){                        printf("[read]:error:%d,n:%d\n", errno, n);                        break;                }                if(strncmp(buf, &buf[PIPE_BUF/2], PIPE_BUF/2)){                        printf("[read]:not equal\n");                        break;                }                if(++num % 1000000 == 0)                        printf("read:%d\n", num);        }}void *writefifo(void *arg){        int     id = ((writeattr*)arg)->id;        int     fd = ((writeattr*)arg)->fd;        char    buf[PIPE_BUF];        memset(buf, '0'+id, PIPE_BUF);        while(run_flag){                write(fd, buf, PIPE_BUF);        }}int main(){        int     stat;        char    fn[]="test.fifo";        int     fd1, fd2, n, s=0;        pthread_t       th_w[WRITENUM], th_r;        int     i;        printf("PIPE_BUF:%d\n", PIPE_BUF);        /* create fifo */        mkfifo(fn, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);        if((fd1 = open(fn, O_RDONLY | O_NONBLOCK, 0)) < 0){                printf("open error\n");                return 10;        }        if((fd2 = open(fn, O_RDWR | O_NONBLOCK, 0)) < 0){                printf("open error\n");                return 20;        }        /* create thread */        run_flag = 1;        for(i=0; i<WRITENUM; i++){                wattr[i].id = i;                wattr[i].fd = fd2;                pthread_create(&th_w[i], NULL, writefifo, &wattr[i]);        }        pthread_create(&th_r, NULL, readfifo, fd1);        /* destroy thread */        pthread_join(th_r, NULL);        for(i=0; i<WRITENUM; i++)                pthread_join(&th_w[i], NULL);        close(fd1);        close(fd2);        return 0;}

0 0