什么时候应该在多线程编程中使用'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;
}
答案 0 :(得分:3)
每当您要读取或写入数据时,都需要锁定它。这可以防止数据尝试读取尚未写入的数据。
另一种说法是,在更改或读取之前,应该锁定线程或进程之间共享的任何数据。
答案 1 :(得分:0)
除了像生产者 - 消费者队列这样的高级别线程间通信的短期锁定之外,我会说“尽可能不随便”。锁会产生死锁,并且死锁的可能性会以超线性的方式与更多的锁相乘。
此外,应用程序中的大量pthread_join()调用为0.&lt; 0是不可能的,1或者更多太多。