1

问题:我有几个文本文件(10),每行都有数字。我需要将它们拆分到我使用 pthread 库创建的一些线程中。创建的这些线程(工作线程)将找到发送给它们的最大素数(以及所有文本文件中的所有最大素数)。

我目前对解决方案的想法:我认为自己有两个数组,一个数组中的所有文本文件,另一个数组将包含一个二进制文件,我可以读取 1000 行并将指针发送到该二进制文件的索引在一个包含 id、文件指针和文件位置的结构中,让它通过它。

我在说的一点点:

pthread_create(&threads[index],NULL,workerThread,(void *)threadFields[index]);//Pass struct to each worker

结构:

typedef struct threadFields{
  int *id, *position;
  FILE *Fin;
}tField;

如果有人有任何见解或更好的解决方案,将不胜感激

编辑:好的,所以我找到了解决问题的方法,我相信它类似于 SaveTheRbtz 的建议。这是我实现的:我把文件合并到一个二进制文件中,并在循环中跟踪它(我必须考虑每个条目有多少字节,这是硬编码的)

struct threadFields *info = threadStruct;
  int index;
  int id = info->id;
  unsigned int currentNum = 0;
  int Seek = info->StartPos;
  unsigned int localLargestPrime = 0;
  char *buffer = malloc(50);
  int isPrime = 0;

    while(Seek<info->EndPos){
    for(index = 0; index < 1000; index++){//Loop 1000 times
    fseek(fileOut,Seek*sizeof(char)*20, SEEK_SET);
    fgets(buffer,20,fileOut);
    Seek++;
    currentNum = atoi(buffer);
    if(currentNum>localLargestPrime && currentNum > 0){
      isPrime = ChkPrim(currentNum);
      if( isPrime == 1)
        localLargestPrime = currentNum;
    }
  }
4

2 回答 2

1

你能做十个线程,每个线程处理一个指定为参数的文件。每个线程将读取自己的文件,检查该值是否大于它迄今为止记录的最大素数,如果是,则检查新数是否为素数。然后,当它完成时,它可以将素数返回给协调器线程。协调线程坐下来等待线程完成,从每个线程中收集最大的质数,并只保留最大的质数。您可能可以使用 0 作为标记值来指示“未找到素数(尚未)”。

假设我想要 11 个线程而不是 10 个;那我将如何分配工作量?

我会pthread_exit()立即执行第 11 个线程。如果你想为自己制造协调问题,你可以,但为什么要让生活变得比你必须做的更难。

如果您绝对必须有 11 个线程处理 10 个文件并分配工作,那么我想我最初可能会在一个队列中设置 10 个文件流。线程将等待条件“队列不为空”以获取文件流(互斥锁和条件等等)。当线程获取文件流时,它会从文件中读取一个数字并将流推回队列(信令队列不为空),然后处理该数字。在 EOF 上,线程将关闭文件而不将其推回队列中(因此线程必须检测“没有未读数据的文件流”)。这意味着每个线程将读取大约十分之一的数据,具体取决于素数计算实际读取的数字所需的时间。这比每个文件一个简单的线程解决方案要复杂得多,但它可以(或多或少地)扩展到任意数量的线程和文件。特别是,它可以用于让 7 个线程处理 10 个文件,以及让 17 个线程处理 10 个文件。

于 2012-12-08T17:10:18.910 回答
0

看起来像消息队列的工作:

  1. 一组“供应商”线程,将数据分成块然后放入队列。在您的情况下,块可以用文件名或 (fd, offset, size) 元组表示。为简单起见,可以有一个这样的供应商。
  2. 从输入队列中提取数据、处理数据并将结果放入另一个队列的“工作”线程数。出于性能原因,通常有很多工作人员,例如,如果您的任务是 CPU 密集型的,那么sysconf(_SC_NPROCESSORS_ONLN)应该是一个不错的选择。
  3. 一个“聚合器”线程将结果队列“减少”为单个值。对于您的情况,这是一个简单的max()功能。

这是一个高度可扩展的解决方案,使您能够轻松地将许多不同类型的处理阶段组合成易于理解的管道。

于 2012-12-09T16:47:46.723 回答