[英]Is a mutex lock needed around a pointer variable?
是否需要在涉及指针间接的代码段周围使用互斥锁(其中指针指向属于临界区的数据)? 示例代码:
struct list {
int i;
struct list *next;
};
int modify_second_elem(struct list *head, int val);
void * func1(void *ptr);
void * func2(void *ptr);
int modify_second_elem(struct list *head, int val) {
if(head == NULL)
return 1;
/* Check to see if second element exists.
Here, I am using indirection to get the next pointer.
Would I need synchronization here? */
if(head->next == NULL)
return -1;
pthread_mutex_lock(&list_lock);
(head->next)->i = val;
pthread_mutex_unlock(&list_lock);
return 0;
}
void * func1(void *ptr) {
struct list *head;
head = (struct list *) ptr;
modify_second_elem(head, 4);
}
void * func2(void *ptr) {
struct list *head;
head = (struct list *) ptr;
modify_second_elem(head, 6);
}
void main() {
struct list *el1, *el2, *el3;
pthread_t th1, th2;
el1 = (struct list *) malloc(sizeof(list));
el2 = (struct list *) malloc(sizeof(list));
el3 = (struct list *) malloc(sizeof(list));
el1->i = 1;
el1->next = el2;
el2->i = 2;
el2->next = el3;
el3->i = 3;
el3->next = NULL;
pthread_create(&th1, NULL, &func1, (void *) el1);
pthread_create(&th2, NULL, &func2, (void *) el1);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
exit(EXIT_SUCCESS);
}
锁用于保护代码中的关键部分 。 如果您的变量处于临界区,那么您需要使用某种锁来保护它。
没有足够的信息给出一个非常好的答案。 如何s
“上发表”给其他线程? 其他线程如何“订阅” s
? struct s
对象存储在什么数据结构中?
所以,我会给出一个通用答案:
线程之间共享的每种数据都需要同步。 这包括共享指针。
关于指针:
您可能听说过,在一些普通的CPU上,正确对齐的指针的加载/存储是原子的(对于所有CPU或所有类型的指针都不是这种情况,例如:x86上的远指针是非原子的)。 如果你没有彻底了解你的CPU / VM内存模型,请远离使用它,如果你不采取锁定(锁提供相当强的保证),有许多微妙的事情可能会出错。
在您的示例中, th1
和th2
都不修改列表,它们只修改列表的元素。 因此,在这种特定情况下,您不需要锁定列表,只需要锁定列表的元素(指针在概念上属于链表实现)。
在更典型的情况下,一些线程将遍历列表,而其他线程将修改列表(添加和删除元素)。 这需要锁定列表,或使用某种无锁算法。
有几种方法可以执行此锁定。
锁用于保护关键部分 。 它与作为指针的变量无关。
在您的情况下,您不需要锁定该检查。 因为s
是参数,所以无法从函数外部访问它。 但是, 它指向的数据不是您的函数的本地数据 ,因此您可能需要锁定对该数据的访问。
这要看你可能有什么其他的操作s
。 例如,另一个线程修改s->c
值取决于s->i
是:
if (s->i == 1) {
s->c = 'x';
} else {
s->c = 'y';
}
在这种情况下,您不能省略互斥锁,否则您可能同时将s->i
设置为1并将s->c
设置为'y'。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.