C中的IPC队列-动态大小的消息

8nuwlpux  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(72)

其目的是在一个文件夹中连接某些文件模式。

abc

字符串
具有带子字符串的文件

score


像score_01.csv score_02.csv score_03.csv和类似的100个文件
下面程序的基本概念是接受两个命令行参数,一个是文件夹,另一个是文件模式。

gcc program.c -o program
./program my_folder score


程序进入my_folder并开始遍历文件,读取它们,然后将它们推入IPC队列。在程序的开头使用pthread启动了一个消费者。这个消费者必须读取和打印。
似乎我没有正确地做msgsnd或msgrcv
此外,如果我尝试在msgsnd之前打印数据缓冲区,它在Mac OS中的打印方式不同-没有问题,而在Ubuntu中,它打印几行,然后出现分散的文本

// File name program.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

key_t key;
int msgid;

typedef struct {
    long msg_type;
    char* buffer;
    size_t length;
} bufferPack;

char* fileBuffer(char* filename) {
    FILE *f = fopen(filename, "rb");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET); 
    char *string = malloc(fsize + 1);
    fread(string, fsize, 1, f);
    fclose(f);
    return string;
} 

void walk_dir(const char *path, char* wildcard)
{
    DIR *dir;
    struct dirent *entry;

    if (!(dir = opendir(path)))
        return;

    while ((entry = readdir(dir)) != NULL) {
        char *name = entry->d_name;
        char full_name[1024];

        if (strstr(name, wildcard ) == NULL )
            continue;

        snprintf(full_name, sizeof(full_name), "%s/%s", path, name);
        bufferPack pack;
        pack.msg_type = 1;
        pack.buffer = fileBuffer(full_name);
        pack.length = strlen(pack.buffer);
        msgsnd(msgid, &pack, sizeof(bufferPack), 0);
    }
    closedir(dir);
}

void* consumer(void* arg) {
    bufferPack pack; 
    while (1) {
        int rec = msgrcv(msgid, &pack, sizeof(bufferPack), 1, 0);    
        if (rec == -1) 
            // No message in queue
            continue;
        printf("%s\n", pack.buffer);
        free(pack.buffer);
    }
}

int main(int argc, char **argv)
{
    if ((key = ftok("/tmp", 'A')) == -1) {
        perror("ftok");
        exit(EXIT_FAILURE);
    }

    if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
        perror("msgget");
        exit(EXIT_FAILURE);
    }

    pthread_t thread;                             
    pthread_create(&thread, NULL, consumer, NULL);

    walk_dir(argv[1], argv[2]);
}

50few1ms

50few1ms1#

strlen(pack.buffer)要求缓冲区是一个空终止字符串。但是fileBuffer()从不添加空终止符(尽管它使用fsize+1为它分配了空间)。

char* fileBuffer(char* filename) {
    FILE *f = fopen(filename, "rb");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET); 
    char *string = malloc(fsize + 1);
    fread(string, fsize, 1, f);
    string[fsize] = '\0'; // add null terminator
    fclose(f);
    return string;
}

字符串

相关问题