这本书说我们需要消除全局或静态数据以保证线程安全。我认为线程安全意味着程序中没有竞争条件。 但是,在下面的示例中,它更改了本地名副其实的" 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;
答案 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
的每次迭代实际上都是一个单独的局部变量。