0

大家好,感谢您的宝贵时间。

我正在尝试并行化一个执行某些命令的程序,我认为 pthreads 将是一个不错的选择。

但我遇到了一些问题。

这是我开始线程的地方:

void timetravel(command_stream_t s)
{

  int *retvals[MAXTHREADS];
  if (s == NULL)
    return;
  if (s->num_commands == 0)
    return;
  int err;
  global_table = create_dependency_table(s);
  //global_command = &s;
  global_command = s;
  int fill = 0;

  for (fill = 0; fill < s->num_commands; fill++)
  {

    global_table.status_table[fill] = 1; //Set all commands to waiting
    // printf("global_table.status_table[i] : %d \n", global_table.status_table[fill]);

  }

  int finished = 0;
  while (finished == 0)

  {
    finished++;
    int threadindex = 0;
    for (threadindex = 0; threadindex < MAXTHREADS; threadindex++)
    {
      err = pthread_create(&(tid[threadindex]), NULL, &parallelexecute, NULL);
      if (err != 0)
        printf("\ncan't create thread :[%s]", strerror(err));
      else
        printf("\n Thread created successfully\n");
    }

    for (threadindex = 0; threadindex < MAXTHREADS; threadindex++)
    {
      pthread_join(tid[threadindex], NULL);
    }

    if (completecheck(global_table) == 0)
    {
      finished = 1;
    }
  }
  //  print_dependency_table(global_table);
  //print_command(global_command->command_array[1]);
}

依赖表是这样存储的

*** DEPENDENCY TABLE ***
 ~x~  ~meh~  ~hello~  ~goodbye~  ~phi~  ~a~  ~gamma~  ~delta~  ~b~  ~c~  ~d~  ~e~  ~f~  ~g~
 1  1  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  1  0  0  0  0  0  0  0  0  0  0  0
 0  0  1  1  1  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  1  1  1  1  1  1

对于命令

cat x meh
echo hello
echo -s hello goodbye > phi
touch a < gamma > delta
touch -rx b c d e f g

由于命令 2 和 3 中使用了“hello”,因此 3 依赖于 2,因此我们有

 ~x~  ~meh~  ~hello~  ~goodbye~  ~phi~  ~a~  ~gamma~  ~delta~  ~b~  ~c~  ~d~  ~e~  ~f~  ~g~
 0  0  1  0  0  0  0  0  0  0  0  0  0  0
 0  0  1  1  1  0  0  0  0  0  0  0  0  0

所以我们不会在 2 之前运行 3

2运行后,我们将它的row设置为0,这样3就不再依赖它了

我没有实现任何类型的阻塞,因为没有写/写冲突。

我们可能有一个竞争条件,即在写入之前有一个读取,但这很好 - 因为它只会延迟线程执行,这是可以的。

这是 pthreads 程序:

void* parallelexecute(void *arg)
{
  //printf("gets to parallel execute stage\n");
  int i;
  //printf("global_table.num_cmds_rows : %d \n",global_table.num_cmds_rows);
  for (i = 0; i < global_table.num_cmds_rows; i++)
  {

    // status 1 = runnable, status 2 = running
    //status 0 = completed successfully, status -1 = unsuccessful
    //printf("global_table.status_table[i] : %d \n",global_table.status_table[i]);

    if (global_table.status_table[i] == 1
        && (check_nth_command(&global_table, i)) == 0)
    {
      global_table.status_table[i] = 2;
      execute_command(global_command->command_array[i], 0);
      printf("execution triggered");
      completed_nth_command(&global_table, i, 0);
      break;
    }
  }
  return NULL;

}

这些是我的全局变量

#define MAXTHREADS 2
pthread_t tid[MAXTHREADS];
 //global variable for dependency pool
parallel_data global_table;
 //global variable for commands
command_stream_t global_command;

但是我注意到当我尝试访问时global_tableparallelexecute我得到了各种奇数值,我不知道为什么。

'global table' 是一个结构,因此:

struct parallel_data
  {
    int** dependency_table;  // the main dependency table
    char** file_reference_key;  // find index by name (use strcmp in a loop)
    int* status_table;  // you know you are done when all the statuses are 0 (none should ever be -1)
    int num_files_cols;  // number of columns/files
    int num_cmds_rows;  // number of rows/commands 
  };

并且每个线程只写在它的行 independency table和它的行 instatus_table

我不太确定如何进行。

我也相当确定支持功能的正确性。

任何帮助,将不胜感激。

4

2 回答 2

1

我还没有阅读你的代码,但是我看到“我没有实现任何类型的阻塞,因为没有写/写冲突”,这对我来说是一个主要的危险信号。如果你有读/写冲突,那么......好吧......你有冲突。这可能与错误有关。唯一有效的情况是您有std::atomic变量或volatile变量,并且快速 CTRL+F 表示您两者都没有。您的代码可能根本没有同步,因此线程永远不会看到其他线程正在写入的值。

于 2013-07-23T19:48:57.377 回答
0

我发现我将参数传递给 pthreads 线程函数的方式是不正确的——我将很快发布我对代码所做的编辑。

谢谢@mooing-duck,@wilx

于 2013-07-31T06:48:47.107 回答