我正在尝试使用pthread互斥变量和barrier来同步我的程序的输出,但它不能按照我想要的方式工作。每个线程每20个值(来自for循环)看到它的最终值,这是正常的,但我试图使它们都达到相同的最终值(如果使用5个线程,所有它们都应该看到100作为最终值,4线程,80等)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int SharedVariable =0;
void *SimpleThread(void *args)
{
int num,val,rc;
int which =(int)args;
rc = pthread_mutex_lock(&mutex1);
for(num=0; num<20; num++){
#ifdef PTHREAD_SYNC
if(random() > RAND_MAX / 2)
usleep(10);
#endif
//pthread_mutex_lock(&mutex1);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
//pthread_mutex_lock(&mutex1);
SharedVariable = val+1;
pthread_mutex_unlock(&mutex1);
}
val=SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
//pthread_mutex_destroy(&mutex1);
//pthread_exit((void*) 0);
//pthread_mutex_unlock(&mutex1);
}
int main (int argc, char *argv[])
{
if(atoi(argv[1]) > 0){
int num_threads = atoi(argv[1]);
//pthread_mutex_init(&mutex1, NULL);
pthread_t threads[num_threads];
int rc;
long t;
rc = pthread_mutex_lock(&mutex1);
for(t=0; t< num_threads; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
//pthread_join(thread1);
}
rc= pthread_mutex_unlock(&mutex1);
}
else{
printf("ERROR: The parameter should be a valid positive number.");
exit(-1);
}
pthread_mutex_destroy(&mutex1);
pthread_exit(NULL);
}
非常感谢任何建议或帮助! 先谢谢!
答案 0 :(得分:2)
在检查最终值之前,您需要使用屏障(pthread_barrier_wait()
) - 这可确保在所有线程都到达屏障之前不会继续执行任何线程。
此外,你应该调用pthread_join()
来等待线程完成,你只需要在增量周围保持互斥:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t barrier1;
int SharedVariable = 0;
void *SimpleThread(void *args)
{
int num,val;
int which = (int)args;
for(num = 0; num < 20; num++) {
#ifdef PTHREAD_SYNC
if(random() > RAND_MAX / 2)
usleep(10);
#endif
pthread_mutex_lock(&mutex1);
val = SharedVariable;
printf("*** thread %d sees value %d\n", which, val);
SharedVariable = val + 1;
pthread_mutex_unlock(&mutex1);
}
pthread_barrier_wait(&barrier1);
val = SharedVariable;
printf("Thread %d sees final value %d\n", which, val);
return 0;
}
int main (int argc, char *argv[])
{
int num_threads = argc > 1 ? atoi(argv[1]) : 0;
if (num_threads > 0) {
pthread_t threads[num_threads];
int rc;
long t;
rc = pthread_barrier_init(&barrier1, NULL, num_threads);
if (rc) {
fprintf(stderr, "pthread_barrier_init: %s\n", strerror(rc));
exit(1);
}
for (t = 0; t < num_threads; t++) {
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, SimpleThread, (void* )t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for (t = 0; t < num_threads; t++) {
pthread_join(threads[t], NULL);
}
}
else {
printf("ERROR: The parameter should be a valid positive number.\n");
exit(-1);
}
return 0;
}
答案 1 :(得分:1)
尝试将pthread_mutext_unlock(&mutext1)
移出SimpleThread
中的for循环。您锁定一次并在原始代码中解锁多次(20)。
或者,您可以在阅读和修改pthread_mutex_lock(&mutext1)
之前将SharedVariable
移至for循环中。在这种情况下,每个线程的add-by-one
操作可能不连续,但每个线程将获得正确的最终值。
在您阅读SharedVariable
的最终值之前,请使用屏障等待所有线程完成其工作。