开发者

Is a mutex lock needed around a pointer variable?

Is a mutex lock needed around a section of code that involves pointer indirection (where the pointer points to data that is part of a critical section)? An example code:

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)
 开发者_如何学JAVA       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);
}


There's not enough information given to give a really good answer. How is s "published" to other threads? How do other threads "subscribe" to s? In what data structure are struct s objects stored?

So, I'll give a generic answer:

Every kind of data that is shared between threads needs synchronization. This includes shared pointers.

About pointers:

You may have heard that on some commonplace CPUs loads/stores of correctly aligned pointers are atomic (this is not the case for all CPUs or for all kinds of pointers, e.g: far pointers on x86 are non-atomic). Stay away from using this if you don't have a thorough understanding of your CPU/VM memory model, there are many subtle things that can go wrong if you don't take locks (locks provide pretty strong guarantees).

Edit:

In your example, neither th1 nor th2 modifies the list, they only modify elements of the list. So, in this specific case, you don't need to lock the list, you just need to lock elements of the list (the pointer conceptually belongs to the linked list implementation).

In more typical cases, some threads would be traversing the list, while others would be modifying the list (adding and removing elements). This requires locking the list, or using some kind of lock-free algorithm.

There are several ways of doing this locking.

  • Have a global lock on the list, and use it also for elements of the list.
  • Use hierarchical locking, have a lock on the list, and a lock on every element. To read/modify an element, you would first take a lock on the list, find the element, take the element's lock, release the list's lock, process the element, and finally release the element's lock. This is useful if you need to do some complex processing on the element and don't want to prevent other threads from accessing the list. You have to take care to always take the locks in the same order, to avoid deadlocks.


Locks are used to protect critical section in the code. If your variable is in critical section, then you will need to protect it with some kind of lock.


It depends on what other operations you may have on s. For example, another thread modifying value of s->c depending on what s->i is:

if (s->i == 1) {
    s->c = 'x';
} else {
    s->c = 'y';
}

In this case you cannot omit the mutex lock otherwise you may have both s->i set to 1 and s->c set to 'y'.


A lock is used to protect critical sections. It has nothing to do with a variable being a pointer or not.

In your case, you don't need to lock that check. Because s is a parameter it cannot be accessed from outside your function. However, the data pointed by it is not local to your function, so you might need to lock access to that data.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜