c - 如何实现并发压缩队列?

时间:2018-03-07 15:26:30

标签: c

问题是我试图制作一个并发压缩工具,这是我的comp函数的代码,它顺序处理来自输入队列的块,但是我试图让它并发。我应该创建一个从输入q中删除和处理块并将它们插入输出q的变量吗?

#define CHUNK_SIZE (1024*1024)
#define QUEUE_SIZE 100

#define COMPRESS 1
#define DECOMPRESS 0


// take chunks from queue in, run them through process (compress or decompress), send them to queue out
void worker(queue in, queue out, chunk (*process)(chunk)) {
    chunk ch, res;
    while(q_elements(in)>0) {
        ch = q_remove(in);

        res = process(ch);
        free_chunk(ch);

        q_insert(out, res);
    }
}

// Compress file taking chunks of opt.size from the input file,
// inserting them into the in queue, running them using a worker,
// and sending the output from the out queue into the archive file
void comp(struct options opt) {
    int fd, chunks, i;
    struct stat st;
    char comp_file[256];
    archive ar;
    queue in, out;
    chunk ch;

    if((fd=open(opt.file, O_RDONLY))==-1) {
        printf("Could not open %s\n", opt.file);
        exit(0);
    }

    fstat(fd, &st);
    chunks = st.st_size/opt.size+(st.st_size % opt.size ? 1:0);

    strncpy(comp_file, opt.file, 256);
    strncat(comp_file, ".ch", 256);

    ar = create_archive_file(comp_file);

    in  = q_create(QUEUE_SIZE);
    out = q_create(QUEUE_SIZE);

    // read input file and send chunks to the in queue
    for(i=0; i<chunks; i++) {
        ch = alloc_chunk(opt.size);

        ch->size = read(fd, ch->data, opt.size);

        q_insert(in, ch);
    }

    // compression of chunks from in to out
    worker(in, out, compress);

    // send chunks to the output archive file
    for(i=0; i<chunks; i++) {
        ch = q_remove(out);

        add_chunk(ar, ch, i);
        free_chunk(ch);
    }

    close_archive_file(ar);
    close(fd);
    q_destroy(in);
    q_destroy(out);
}


// Decompress file taking chunks of opt.size from the input file,
// inserting them into the in queue, running them using a worker,
// and sending the output from the out queue into the decompressed file

void decomp(struct options opt) {
    int fd, i;
    struct stat st;
    char uncomp_file[256];
    archive ar;
    queue in, out;
    chunk ch;

    if((ar=open_archive_file(opt.file))==NULL) {
        printf("Could not open archive file\n");
        exit(0);
    };

    strncpy(uncomp_file, opt.file, strlen(opt.file) -3);
    uncomp_file[strlen(opt.file)-3] = '\0';

    if((fd=open(uncomp_file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH))== -1) {
        printf("Could not create %s: %s\n", uncomp_file, strerror(errno));
        exit(0);
    } 

    in  =q_create(QUEUE_SIZE);
    out =q_create(QUEUE_SIZE);

    // read chunks with compressed data
    for(i=0; i<chunks(ar); i++) {
        ch = get_chunk(ar, i);
        q_insert(in, ch);
    }

    // decompress from in to out
    worker(in, out, decompress);

    // write chunks from output to decompressed file
    for(i=0; i<chunks(ar); i++) {
        ch=q_remove(out);
        write(fd, ch->data, ch->size);
        free_chunk(ch);
    }

    close_archive_file(ar);    
    close(fd);
    q_destroy(in);
    q_destroy(out);
}

int main(int argc, char *argv[]) {    
    struct options opt;

    opt.compress=COMPRESS;
    opt.num_threads=3;
    opt.size=CHUNK_SIZE;
    opt.queue_size=QUEUE_SIZE;

    read_options(argc, argv, &opt);

    if(opt.compress==COMPRESS) comp(opt);
    else decomp(opt);
}

0 个答案:

没有答案