【问题标题】:Cat unix command multithread implementationcat unix命令多线程实现
【发布时间】:2014-03-16 16:26:13
【问题描述】:

您好,我正在尝试实现比提供的更快的 cat。

我当前的实现如下所示:

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define BUF_SIZE 1024*1024*1024

char buffer[BUF_SIZE];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_var2 = PTHREAD_COND_INITIALIZER;
int readed = 0;
/*
    Read characters from standard input and saves them to buffer
*/
void *consumer(void *data) {
    int r;
    while(1) {
        //---------CRITICAL CODE--------------
        //------------REGION------------------
        pthread_mutex_lock(&mutex);
        if (readed > 0)
        {
            pthread_cond_wait(&cond_var2, &mutex);
        }
        r = read(0, buffer, BUF_SIZE);
        readed = r;

        pthread_cond_signal(&cond_var);
        pthread_mutex_unlock(&mutex);
        //------------------------------------

        if (r == -1){
            printf("Error reading\n");
        }  
        else if (r == 0) {
            pthread_exit(NULL);
        }
    }
}

/*
    Print chars readed by consumer from standard input to standard output
*/
void *out_producer(void *data) {
    int w;
    while(1){    
        //---------CRITICAL CODE--------------
        //-------------REGION-----------------
        pthread_mutex_lock(&mutex);
        if (readed == 0)
        {
            pthread_cond_wait(&cond_var, &mutex);
        }
        w = write(1, buffer, readed); 
        readed = 0;
        pthread_cond_signal(&cond_var2);
        pthread_mutex_unlock(&mutex);
        //------------------------------------ 

        if (w == -1){
            printf("Error writing\n");
        } 
        else if (w == 0) {
            pthread_exit(NULL);
        }
    }
}

你有什么建议让它更快? 有任何想法吗? 我在考虑 BUF_SIZE,你认为缓冲区的最佳大小是多少?

Main 只创建线程:

int main() {
    //  Program RETURN value
    int return_value = 0;

    //  in - INPUT thread
    //  out - OUTPUT thread
    pthread_t in, out;

    //  Creating in thread - should read from standard input (0)
    return_value = pthread_create(&in , NULL, consumer, NULL);
    if (return_value != 0) {
        printf("Error creating input thread exiting with code error: %d\n", return_value);
        return return_value;
    }

    //  Creating out thread - should write to standard output (1)
    return_value = pthread_create(&out, NULL, out_producer, NULL);
    if (return_value != 0) {
        printf("Error creating output thread exiting with code error: %d\n", return_value);
        return return_value;
    }

    return_value = pthread_join(in, NULL);
    return_value = pthread_join(out, NULL);

    return return_value;
}

【问题讨论】:

  • 1GB 绝对不是一个合理的缓冲区大小......
  • 你有什么建议?我还将对大小超过 10GB 的文件使用 cat
  • 你认为线程为什么会让cat更快?
  • 我不知道我只是为了好玩而做一些实验,我想学习如何使用线程。
  • SzG 所说的。如果这不仅仅是多线程编程的练习,而是让 cat 更快的真正尝试,我认为你走错了路。要知道如何真正让它更快,我们需要更多地了解您的使用案例。如果它与管道一起使用,管道几乎肯定是限制因素,但您可以通过更改管道缓冲区大小和使用 splice-family 函数来改进(以特定于 Linux 的方式)。

标签: c unix pthreads concatenation cat


【解决方案1】:

cat 添加线程究竟如何使其更快?您不能只对任何程序进行并行处理并期望它运行得更快。

Cat 基本上只是将每一行输入(通常来自文件)传输到输出。由于线路有序很重要,因此您必须使用互斥来避免赛车。

并行的速度上限(cat 可以运行的最快速度)不能高于串行的cat,因为每个线程都必须执行串行操作,以及同步成本。

【讨论】:

  • 它可以稍微快一点,因为下一个数据单元的读取可以与前一个数据单元的写入并行进行。
  • @R..,操作系统应该自己注意到(或从程序中获得明确提示)它正在按顺序读取,并适当地安排预读。
  • @vonbrand:它可以做到这一点,但它仍然无法提前安排读取用户空间进程的地址空间。这是我看到多线程实现的潜力(仍然非常有限)的唯一一点。
  • 实际上在 >1GB 文件上,我得到的结果比使用 os cat 命令(我添加了第二个缓冲区并使缓冲区大小为 1024*1024/4)稍好一些,因此当第一个缓冲区被填充时,第二个正在写入。但它的差异仍然是大约 +-0,0x 秒
猜你喜欢
  • 2013-07-27
  • 1970-01-01
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多