when should I use 'lock' in multi-thread programing? Just lock the area which each thread will modify or lock the area which each thread can access even it will not be modified ?
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.
Thanks for your attention, and If you have more time, The more detail about real code:
/*
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;
}