我是多线程技术的新手,所以,如果这个问题看起来很愚蠢,请和我一起裸露。我有一个很大的文件要阅读,请执行以下操作。
[当我在单线程C代码中执行上述序列时,它工作正常,现在我试图通过创建3个线程(我有使用3个线程来使此过程更快的任务)来使用多线程来使其更快。并进行比较,但我这样做失败,因为我发现它只是重复了一些比较。
我是否有某种方法可以使用3个线程读取文件的3个不同部分并执行某些操作?预先谢谢你。
请注意,这个答案是'trick'(或者可能是分配是一个把戏?),因为它并没有真正使过程更快。答案假定具有合理(4G +)内存的标准Linux计算机。
简短的回答:在任何半适当的配置中,数据将移入OS缓冲区,而问题实际上是CPU约束的,而不是IO约束的。
长回答:
尽管50MB的文件对于人类来说是“大”,但对于每台现代计算机来说,它都是“小”。实际上,除非系统需要内存来执行其他任务,否则数据将移入OS缓冲区并保持在那里。
鉴于数据位于(OS)内存中,问题(不是初始调用)不是IO绑定的,而是CPU的绑定。对于此3线程MT程序将发挥作用。问题成为如何将工作分散到3个文件中。理想情况下,这3个线程会将文件划分为3个(几乎)相等的块,每个块均由自身处理。
解决方案是伪代码,实际代码将不得不处理分割成块的行,错误检查等。
FILE *data_fp ;
static int block_size ;
main() {
data_fp = fopen(...) ;
int filesize = ftell(fp) ;
block_size = filesize/6 ;
for (int i=0 ; i<N_THREADS ; i++ ) {
start_offset = filefize*((float i)/N_THREADS) ;
pthread_create(search_start, ... , &start_offset) ;
}
}
search_start(void *arg) {
// Extract the offset to start
long start_offset = * (long *) arg ;
// Create separate FILE*, with separate position, buffers, etc.
FILE *local_fp = fdopen(fileno(data_fp), "r") ;
// Position at the thread specific offset
fseek(local_fp, start_offset, SEEK_SET) ;
char buff[256] ; // max line size
// Loop until EOF, some exit condition, or block_size characters processed
for (long p = 0 ; p < block_size && fgets(buff, sizeof(buff), local_fp) ; p += strlen(buff)) {
// Compare, check, whatever is needed
...
if (need_to_stop) break ;
} ;
fclose(local_fp) ;
}
使用'mmap'可能使其更快。但是,问题要求进行行处理,并且鉴于这不是实际问题,因此不确定是否值得付出额外的努力。