程序打开同一个命名管道并用 C 多次写入

Posted

技术标签:

【中文标题】程序打开同一个命名管道并用 C 多次写入【英文标题】:Program opens the same named pipe and writes to it many times with C 【发布时间】:2017-04-08 06:48:06 【问题描述】:

我创建了两个程序,它们将通过命名管道进行通信,一个将读取它,另一个将写入它。它现在工作得很好,除了它打开并写入同一个 fifo 恰好 3 次。这是我第一次使用C和管道,我不明白为什么要写三遍。你能明白为什么这篇文章写了三遍吗?

写作.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <dirent.h>
#include <sys/stat.h>  
#include <sys/types.h>
#include <fcntl.h>

#define BUFFSIZE 512
#define err(mess)  fprintf(stderr,"Error: %s.", mess); exit(1); 


void writing(char *s)

    int fd;
    ssize_t n;

    char buf[BUFFSIZE];

    printf("writing to %s\n",s);
    if ( (fd = open(s, O_WRONLY)) < 0)
        err("open")

    while( (n = read(STDIN_FILENO, buf, sizeof buf -1) ) > 0) 
    buf[n-1] = '\0';

        printf("Received: %s\n", buf);

        if ( write(fd, buf, n) != n)  
            err("write");
        
    if(strcmp(buf,"END")==0)
           printf("%s","exit");
       break;
        
    
    close(fd);


char* concat(const char *s1, const char *s2)

    char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
    strcpy(result, s1);
    strcat(result, s2);
    return result;


int file_stat(char *argv)

           int isfifo = 0;
       struct stat sb;

           printf("%s",argv);

           if (stat(argv, &sb) == -1) 
               perror("stat");
               exit(EXIT_FAILURE);
           

           printf("File type:                ");

           if (sb.st_mode & S_IFMT == S_IFIFO) 
            printf("FIFO/pipe\n");
        isfifo = 1;

           

           printf("Ownership:                UID=%ld   GID=%ld\n",
                   (long) sb.st_uid, (long) sb.st_gid);


           //exit(EXIT_SUCCESS);
       return isfifo;






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

    // READ ALL FILES IN DIRECTORY
    if (argc != 2) 
               fprintf(stderr, "Usage: %s /<pathname>/\n", argv[0]);
               exit(EXIT_FAILURE);
           
    DIR *d;
    struct dirent *dir;
    if ((d = opendir (argv[1])) != NULL) 
        /* print all the files and directories within directory */
        while ((dir = readdir (d)) != NULL) 
                printf ("%s\n", dir->d_name);
            char* s = concat(argv[1], dir->d_name);
            if (file_stat(s) == 1) 
                writing(s);
            
            else 
                mkfifo("fifo_x", 0666);
                writing("fifo_x");      
            
            free(s);
        
        closedir (d);
    
    else 
        /* could not open directory */
        perror ("error: ");
        return EXIT_FAILURE;
    

除了“读取”函数和调用reading()之外,读取文件是相同的 阅读

void reading(char *s)

    int fd;
    ssize_t n;
    char buf[BUFFSIZE];
    printf("%s",s);

    if ( (fd = open(s, O_RDONLY)) < 0)
        err("open");


    while( (n = read(fd, buf, sizeof buf - 1) ) > 0) 

    buf[n-1] = '\0';
    if(strcmp(buf,"END")==0)
           printf("%s\n", "exit");
       break;
        
    buf[n-1] = '\n';
    if ( write(STDOUT_FILENO, buf, n) != n)  
            exit(1);
        
    
    close(fd);

输出

/home/..File type:                Ownership:                UID=0   GID=0
writing to fifo_x
END
Received: END
exitola
/home/olaFile type:                Ownership:                UID=1001   GID=1001
writing to fifo_x
END
Received: END
exit.
/home/.File type:                Ownership:                UID=0   GID=0
writing to fifo_x
END
Received: END
exit

【问题讨论】:

当你运行一个程序时,它会写三遍。为什么要写三遍是你的问题吗? 是的。我在问为什么我的程序打开同一个管道并多次写入同一个管道(恰好是三个)。 【参考方案1】:

在您调用程序的路径名的目录中有三个文件。这三个文件都不是先进先出的,所以对于你写给fifo_x的每个文件。

文件名是

    .
    ..
    olaFile

也许您应该明确排除文件

    .
    ..

恰好在linux的每个目录中,代表当前目录.和父目录..

【讨论】:

以上是关于程序打开同一个命名管道并用 C 多次写入的主要内容,如果未能解决你的问题,请参考以下文章

c中的命名管道

检测命名管道的关闭

在多个进程写入时读取命名管道

Linux:打开命名管道进行写入时超时

从命名管道并发选择

无法打开 Windows 命名管道进行写入?