管道读取最大元素数?

问题描述 投票:0回答:1

我尝试编写一个简单的读写器程序。

读者:

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

#define BUFFSIZE 65600 //921600 // 640*480*3
#define err(mess) { fprintf(stderr,"Error: %s.", mess); exit(1); }

int main()
{
    int fd;
    ssize_t n;
    char buf[BUFFSIZE];
    long int i;

    if ( (fd = open("./shared/test", O_RDONLY)) < 0)
        err("open")

    while( (n = read(fd, buf, BUFFSIZE) ) > 0) {
        printf("Read (%d): ", n);
        for (i=0; i<BUFFSIZE; i++)
            printf("%c", buf[i]);
        printf("\n");
    }
    close(fd);
    
    return 0;
}

作者:

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

#define BUFFSIZE  65600 //921600 // 640*480*3
#define err(mess) { fprintf(stderr,"Error: %s.", mess); exit(1); }


int main()
{
    int fd;
    char buf[BUFFSIZE];
    long int i, j;

    mkfifo("./shared/test", 0666);
    if ( (fd = open("./shared/test", O_WRONLY)) < 0)
        err("open")

    // main loop
    j=0;
    while (1){
    for (i=0;i<BUFFSIZE;i++){
        buf[i]= j + '0';
    }
    j++;
    buf[BUFFSIZE-1]=j + '0';
    
    write(fd, buf, sizeof(buf));
    sleep(10);
    }

    close(fd);
    
    return 0;
}

程序可以正确运行到 BUFFSIZE 65535 (2^16-1)。 当我尝试使用更大的数字时,它给了我例如: 读取 (65536): 0000000000000000000000000000000000000 以及垃圾元素之后

如何将它用于更多数量的元素? 谢谢, 乔

c linux pipe ipc named-pipes
1个回答
0
投票

如果您正确检查缓冲区,则两个程序不需要具有相同的缓冲区大小。 这就是管道的想法。 检查 read() 和 write() 调用是否有不完整的写入或读取非常重要,并且要考虑到如果读取未读取完整的缓冲区,则其余部分将没有要打印的有趣数据。 检查您的代码副本(在您犯错误的地方进行更正)并查看情况如何。

读者.c

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

#define BUFFSIZE 65600 //921600 // 640*480*3
#define err(mess) { fprintf(stderr,"Error: %s.", mess); exit(1); }

int main()
{
    int fd;
    ssize_t n;
    char buf[BUFFSIZE];
    long int i;

    mkfifo("test", 0666);
    if ( (fd = open("test", O_RDONLY)) < 0)
        err("open")

    while( (n = read(fd, buf, BUFFSIZE) ) > 0) {
        printf("Read (%zd): ", n);
        /* you cannot warrant that
         * BUFFSIZE chars have been read, so use
         * n, instead of BUFFSIZE */
        for (i = 0; i < n && i < 32; i++)
            printf("%c", buf[i]);
        if (i >= 32) printf("...\n");
        printf("\n");
    }
    if (n < 0) {
        err(strerror(errno));
    }
    close(fd);

    return 0;
}

作家.c

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

#define BUFFSIZE  921600 // 640*480*3
#define err(mess) { fprintf(stderr,"Error: %s.", mess); exit(1); }

int main()
{
    int fd;
    char buf[BUFFSIZE];
    long int i, j;

    mkfifo("test", 0666);
    if ( (fd = open("test", O_WRONLY)) < 0)
        err("open")

    /* you only need to do this once, as you never
     * change the buffer contents. */
    char *p = buf;
    for (i = 1; i <= BUFFSIZE; i++, p++) {
        /* this will write the pattern ....,....;....,....;
         * in the buffer. */
        switch(i % 10) {
        case 5:  *p = ','; break;
        case 0:  *p = ';'; break;
        default: *p = '.'; break;
        }
    }
    /* hmmmm.... j + '0'??? sure? I think you need
     * this, instead: */
    // buf[BUFFSIZE-1]='\0';  // '0' is not the same as '\0'

    /* but you don't need it, as you tell write() where to
     * stop writing */

    // main loop
    for (j = 0;; j++) {
        /* as you defined buf of BUFFSIZE chars, sizeof buf will be
         * that number, if you specify sizof(buf) you will write the
         * last \0 char, and you don't want that to occur... or yes? */
        printf("#%ld:\n", j);

        ssize_t n;
        char *p = buf;
        size_t to_go = sizeof buf;
        while ((n = write(fd, p, to_go)) > 0) {
            p     += n; /* advance the pointer n positions */
            to_go -= n; /* reduce the chars to go in n */
        }
        if (n < 0) {
            /* we got out of the loop because n < 0, this is because
             * an error happened to write() */
            err(strerror(errno));
        }
        sleep(10);
    }

    close(fd);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.