什么时候我应该在多线程编程中使用'lock'?

时间:2012-07-12 02:06:43

标签: multithreading pthreads pthread-join

什么时候应该在多线程编程中使用'lock'?只需锁定每个线程将修改的区域或锁定每个线程可以访问的区域,即使它不会被修改?

struct share_data {
    /* share data */
    thread_id;
}

thread 1 will exceute main() function:
   Initial share data. /* need lock */

   join all thread(share_data.thread_id, &status)   /* access share data thread_id, lock or not? */
   exit.

other threads will:
   access share_data, /* lock or not? */
   modify share_data, /* lock */
   exit.

感谢您的关注,如果您有更多时间,有关实际代码的详细信息:

/* 
the number of threads will be input by user. Structure "tdata" and "tlist" stores 
information of each thread, including: "tid" - thread id which is gaven by 1st argument 
of pthread_create(), "torder" which is the order of calling pthread_create() for each 
thead, "status" stores work status of each thread. I allocate memory for "tlist" 
dynamically. Now, we assume that the number of threads is NUM_THREADS(5). I do not use 
the 4th argument to pass data to each thread, I use global variable "tdata", "tlist" as 
shared data to them. "mutex" variable is used to make sure those threads share data safely,
but it seems not works correctly.

I wanna each thread can get "torder", and maybe modify the status before calling 
pthread_exit().
*/
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

/* #define NUM_THREADS 5 */
struct tdata {
        pthread_t tid;
        int torder;
        int status;
        struct tdata *next;
};
typedef struct tdata tdata_t;
struct tdatalist {
        tdata_t *head;
        tdata_t *tail;
}tlist;

pthread_mutex_t mutex;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *tfunc() {
        tdata_t *p, *q;
        unsigned long int tid;
        int torder;

        p = tlist.head;
        q = NULL;
        pthread_mutex_lock(&mutex);

        tid = pthread_self();

        while (p->tid!=tid && p->next!=NULL) {
                q = p;
                p = p->next;
        }
        tid = p->tid;
        torder = p->torder;
        /* p->status = 0; */
        pthread_mutex_unlock(&mutex);
        /* printf ("I am thread %lu, myorder %d, thread_exit.\n", tid, torder); */
        printf ("I am thread %0x, myorder %d, thread_exit.\n", tid, torder);

        pthread_exit((void *)torder);
}

int main (int argc, char *argv[]) {
/*        pthread_t thread[NUM_THREADS]; */

        pthread_attr_t attr;
        int t;
        tdata_t *tdata_p;
        int num_threads;
        printf ("Input number of threads:");
        scanf ("%d", &num_threads);
        printf ("\n");

        printf ("Main thread id: %08x\n", pthread_self());

        pthread_mutex_init(&mutex, NULL);
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

        tlist.head=tlist.tail=NULL;     /* create and initial tlist */
        for (t=0; t<num_threads; t++) {

                pthread_mutex_lock(&mutex);
                tdata_p = (tdata_t *) malloc (sizeof (tdata_t));
                pthread_create (&tdata_p->tid, &attr, tfunc, NULL);
                /* tdata_p->tid = thread[t]; */
                tdata_p->torder = t;
                tdata_p->status = 1;          /* for 0,finished the work.  for 1,not*/
                tdata_p->next = NULL;

                if(tlist.head == NULL) {
                        tlist.head = tlist.tail = tdata_p;
                }
                else {
                        tlist.tail->next = tdata_p;
                        tlist.tail = tdata_p;
                }
                pthread_mutex_unlock(&mutex);

        }

        /*  Join child threads */
        pthread_attr_destroy(&attr);
        pthread_mutex_lock (&mutex);
        tdata_t *p;
        tdata_t *q;
        void *status;
        p = tlist.head;
        while (p != NULL) {
                q = p->next;
                pthread_join(p->tid, &status);
                p = q;
        }

        pthread_mutex_unlock (&mutex);

        pthread_mutex_destroy(&mutex);
        /* delete the list */
        p = tlist.head;
        while (p != NULL) {
                q = p->next;
                free (p);
                p = q;
        }
        tlist.head = tlist.tail = NULL;

        printf ("Main exit.\n");
        pthread_exit(NULL);

        return 0;
}

2 个答案:

答案 0 :(得分:3)

每当您要读取或写入数据时,都需要锁定它。这可以防止数据尝试读取尚未写入的数据。

另一种说法是,在更改或读取之前,应该锁定线程或进程之间共享的任何数据。

答案 1 :(得分:0)

除了像生产者 - 消费者队列这样的高级别线程间通信的短期锁定之外,我会说“尽可能不随便”。锁会产生死锁,并且死锁的可能性会以超线性的方式与更多的锁相乘。

此外,应用程序中的大量pthread_join()调用为0.&lt; 0是不可能的,1或者更多太多。