如何使用lock_mutex或sleep函数强制三个线程再次打印“ hello world”?我已经完成了...
/* t2.c
synchronize threads through mutex and conditional variable
To compile use: gcc -o t2 t2.c -lpthread
*/
#include <stdio.h>
#include <pthread.h>
void hello(); // define three routines called by threads
void world();
void again(); /*new statment*/
/* global variable shared by threads */
pthread_mutex_t mutex; // mutex
pthread_cond_t done_hello; // conditional variable
int done = 0; // testing variable
int main(int argc, char* argv[])
{
pthread_t tid_hello, // thread id
tid_world, tid_again;
/* initialization on mutex and cond variable */
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&done_hello, NULL);
pthread_create(&tid_hello, NULL, (void*)&hello, NULL); //thread creation
pthread_create(&tid_world, NULL, (void*)&world, NULL); //thread creation
pthread_create(&tid_again, NULL, (void*)&again, NULL); //thread creation/*new statment*/
/* main waits for the three threads to finish by order */
pthread_join(tid_hello, NULL);
pthread_join(tid_world, NULL);
pthread_join(tid_again, NULL); /*new statment*/
printf("\n");
return 0;
}
void hello()
{
pthread_mutex_lock(&mutex);
printf(" hello");
fflush(stdout); // flush buffer to allow instant print out
done = 2;
pthread_cond_signal(&done_hello); // signal world() thread
pthread_mutex_unlock(&mutex); // unlocks mutex to allow world to print
return;
}
void world()
{
pthread_mutex_lock(&mutex);
/* world thread waits until done == 1. */
while (done == 1)
pthread_cond_wait(&done_hello, &mutex);
printf(" world");
fflush(stdout);
pthread_mutex_unlock(&mutex); // unlocks mutex
return;
}
void again() /*new function*/
{
pthread_mutex_lock(&mutex);
/* again thread waits until done == 0. */
while (done == 0)
pthread_cond_wait(&done_hello, &mutex);
printf(" again");
fflush(stdout);
pthread_mutex_unlock(&mutex); // unlocks mutex
return;
}
答案 0 :(得分:1)
是的,可以。但是您应该使用几个pthread_cond_t
信号:
"hello"
的一个"world"
的一个。有效地来自man pthread_cond_wait()
:
对于同一条件变量的并发pthread_cond_timedwait()或pthread_cond_wait()操作使用多个互斥锁的效果未定义;也就是说,当线程等待条件变量时,条件变量将绑定到唯一的互斥体,并且该(动态)绑定将在等待返回时终止。
每个world
和again
函数都必须等待自己的信号。
#include <stdio.h>
#include <pthread.h>
void * hello(void*);
void * world(void*);
void * again(void*);
/* global variable shared by threads */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t done_hello = PTHREAD_COND_INITIALIZER;
pthread_cond_t done_world = PTHREAD_COND_INITIALIZER;
int main(void)
{
pthread_t threads[3];
pthread_create(&threads[0], NULL, hello, NULL);
pthread_create(&threads[1], NULL, world, NULL);
pthread_create(&threads[2], NULL, again, NULL);
for(int i = 0; i < 3; ++i)
pthread_join(threads[i], NULL);
printf("\n");
return 0;
}
void * hello(void* foo)
{
pthread_mutex_lock(&mutex);
printf(" hello");
fflush(stdout);
pthread_cond_signal(&done_hello);
pthread_mutex_unlock(&mutex);
return NULL;
}
void * world(void* foo)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&done_hello, &mutex);
printf(" world");
fflush(stdout);
pthread_cond_signal(&done_world);
pthread_mutex_unlock(&mutex);
return NULL;
}
void * again(void* foo)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&done_world, &mutex);
printf(" again");
fflush(stdout);
pthread_mutex_unlock(&mutex);
return NULL;
}
答案 1 :(得分:0)
要正确使用condvar,请考虑以下事项:
void *thread(void *arg)
{
static char str[] = { "hello", "world", "again" };
int value = (int)(intptr_t)arg;
/* wait for the condition (done == value) to be true */
pthread_mutex_lock(&mutex);
while (done != value) {
pthread_cond_wait(&done_hello, &mutex);
}
pthread_mutex_unlock(&mutex);
/* release all locks to decrease latency during our work */
printf(" %s", str[value]);
/* reacquire the lock to update done */
pthread_mutex_lock(&mutex);
done++;
/* notify anybody that might be waiting for done */
pthread_cond_broadcast(&done_hello);
/* permit others to continue */
pthread_mutex_unlock(&mutex);
return NULL;
}
与您的代码有些不同,但是让所有线程运行相同的代码可以建立对代码正确性的信心,并减少不正确代码的调试工作。请注意如何使用条件:lock(); while (!condition) wait(); unlock();
和lock(); setcondition(); broadcast(); unlock();
broadcast(); unlock();
的顺序无关紧要,只要您在它们之间不做任何操作即可。选择一个惯例,并坚持下去;当您需要破坏它时,它可以作为某些事情正在发生的线索。