Multithreading 我应该在什么时候使用';锁';在多线程编程中?
我应该在多线程编程中何时使用“锁定”?只需锁定每个线程将要修改的区域,或者锁定每个线程即使不修改也可以访问的区域Multithreading 我应该在什么时候使用';锁';在多线程编程中?,multithreading,pthreads,pthread-join,Multithreading,Pthreads,Pthread Join,我应该在多线程编程中何时使用“锁定”?只需锁定每个线程将要修改的区域,或者锁定每个线程即使不修改也可以访问的区域 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)
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;
}
/*
线程数将由用户输入。结构“tdata”和“tlist”存储
每个线程的信息,包括“tid”-由第一个参数指定的线程id
对于pthread_create(),“torder”,这是为每个线程调用pthread_create()的顺序
thead,“status”存储每个线程的工作状态。我为“tlist”分配内存
动态地。现在,我们假设线程数为NUM_threads(5)。我不使用
在向每个线程传递数据的第四个参数中,我使用全局变量“tdata”、“tlist”作为
向他们共享数据。“mutex”变量用于确保这些线程安全地共享数据,
但它似乎不能正常工作。
我想每个线程都能得到“torder”,在调用之前修改状态
pthread_exit()。
*/
#包括
#包括
#包括
#包括
/*#定义NUM_线程5*/
结构数据{
pthread_t tid;
内特托德;
智力状态;
结构tdata*下一步;
};
typedef struct tdata tdata\t;
结构tdatalist{
t数据头;
t数据*尾部;
}tlist;
pthread_mutex_t mutex;
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
void*tfunc(){
t数据*p,*q;
无符号长整数tid;
内特托德;
p=t列表头;
q=零;
pthread_mutex_lock(&mutex);
tid=pthread_self();
而(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(“我是线程%lu,我的订单%d,线程\u退出。\n”,tid,torder)*/
printf(“我是线程%0x,myorder%d,线程\u退出。\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_线程;
printf(“输入线程数:”);
扫描F(“%d”,&num线程);
printf(“\n”);
printf(“主线程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;/*创建并初始化tlist*/
对于(t=0;ttid,&attr,tfunc,NULL);
/*tdata_p->tid=线程[t]*/
t数据p->torder=t;
tdata_p->status=1;/*对于0,已完成工作。对于1,未完成工作*/
tdata_p->next=NULL;
if(tlist.head==NULL){
tlist.head=tlist.tail=tdata\u p;
}
否则{
tlist.tail->next=tdata\u p;
tlist.tail=tdata\u p;
}
pthread_mutex_unlock(&mutex);
}
/*连接子线程*/
pthread_attr_destroy(&attr);
pthread_mutex_lock(&mutex);
tdata_t*p;
tdata_t*q;
无效*状态;
p=t列表头;
while(p!=NULL){
q=p->next;
pthread_join(p->tid,&status);
p=q;
}
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
/*删除列表*/
p=t列表头;
while(p!=NULL){
q=p->next;
自由基(p);
p=q;
}
tlist.head=tlist.tail=NULL;
printf(“主出口。\n”);
pthread_exit(NULL);
返回0;
}
任何时候您要读取或写入数据,都需要将其锁定。这可以防止数据尝试读取尚未写入的数据
另一种说法是,在更改或读取之前,线程或进程之间共享的任何数据都应该被锁定。除了对更高级别的线程间通信(如生产者-消费者队列)的短期锁定之外,我的回答是“尽可能不频繁地”。锁生成死锁,死锁的概率以超线性方式倍增,锁越多
此外,应用程序中调用pthread_join()的次数通常为0。您需要锁定对共享数据的所有读/写访问。通常,您应该在需要访问可变数据时锁定,并且您希望确保在访问或修改数据时没有其他线程访问或修改数据。实际上,这意味着,一旦锁定了关键代码区域,进入同一关键区域(即访问同一数据)的任何其他线程都必须等到您解除锁定后才能进入关键区域或访问同一数据。换句话说,访问共享_数据:lock;修改共享数据:锁定;但是当我使用pthread连接线程时,pthread_join()的第一个参数存储在共享数据结构中。如果锁定pthread_join(),则会发生死锁,因为在主线程中调用的pthread_join()将挂起等待线程终止,并且线程可能会等待主线程承载的锁。我该怎么做?调用pthread_join时,您不必担心死锁。pthread_join只能由终止线程调用,这意味着在调用pthread_close时,其他线程所依赖的main中的所有数据都应该已写入,并且锁已被移除。如果您将要加入的线程指定为等待变量,则pthread join的结果将存储在中,您将被保证死锁。如果需要通过检查该值来检查另一个线程是否正在等待线程,则应使用条件状态