对C中的线程安全和竞争条件感到困惑

时间:2015-12-06 02:20:52

标签: c multithreading thread-safety

这本书说我们需要消除全局或静态数据以保证线程安全。我认为线程安全意味着程序中没有竞争条件。 但是,在下面的示例中,它更改了本地名副其实的" Point pt_ptr"从非指针类型到指针类型" Point * pt_ptr"为了防止竞争条件。我注意到他使用" malloc",这意味着他将在堆中创建一些东西。并且堆中的东西由所有线程共享......因为它创建了共享的东西,它会阻止数据竞争但它是否是线程UNSAFE?



int main(void) {
  pthread_t tids[NUM_THREADS];
  int i;
  Point *pt_ptr;

  for (i= 0; i < NUM_THREADS; i++) {
    pt_ptr= malloc(sizeof(*pt_ptr));
    pt_ptr->x= i;
    pt_ptr->y= 3 * i + 2;
    pthread_create(&tids[i], NULL, print_point, pt_ptr);
  }
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

如果多个线程尝试访问相同的内存空间(作为示例变量)而没有某些线程安全机制(例如互斥锁或信号量),那么它将只是线程不安全。它们用于提供阻塞机制,以便一个线程可以坐下来等待&#34;直到当前拥有的线程通过,此时第二个线程将具有访问/修改变量的能力。

将它们视为DMV上的数字,你必须等到你的电话被叫到才能获得服务。

答案 1 :(得分:1)

在这种情况下,循环的每次迭代都会调用malloc(),从而创建一个仅传递给一个线程的新内存块。 (正如J. Murray正确指出的那样。)这些动态变量根本不是全球性的。你可以写一下:

int main(void)
{
  pthread_t tids[NUM_THREADS];

  for ( int i = 0; i < NUM_THREADS; i++) {
    Point * const pt_ptr = malloc(sizeof(*pt_ptr));
    assert(pt_ptr);  /* TODO: Handle the out-of-memory error. */
    pt_ptr->x= i;
    pt_ptr->y= 3 * i + 2;
    pthread_create(&tids[i], NULL, print_point, pt_ptr);
  }
  /* ... */
  return EXIT_SUCCESS;
}

该版本更清楚地表明pt_ptr的每次迭代实际上都是一个单独的局部变量。