Pthreads在执行时更新全局2D阵列段错误

时间:2013-07-23 18:57:14

标签: c concurrency pthreads global-variables pthread-join

大家好,谢谢你的时间。

我正在尝试并行执行某些命令的程序,我认为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

As&#34;你好&#34;在命令2和3中使用,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之后,我们将其行设置为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_table访问parallelexecute时,我注意到我得到了各种奇怪的值,我不知道为什么。

&#39;全球表&#39;因此是一个结构:

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 
  };

并且每个线程仅在dependency table的行上写入,而在status_table中的行

我不太清楚如何继续。

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

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我发现我向pthreads线程函数传递参数的风格是不正确的 - 我将很快发布我对代码所做的编辑。

谢谢@ mooing-duck,@ wilx