【发布时间】:2016-05-09 01:37:50
【问题描述】:
我有 4 个线程 (Thread_A - Thread_D)。我希望它们以 A、B、C、D 的顺序结束。必须用信号量来解决。
我的代码有什么问题?大多数情况下都可以,但有时顺序错误。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
void* thread_A (void *arg);
void* thread_B (void *arg);
void* thread_C (void *arg);
void* thread_D (void *arg);
typedef struct sem_package {
sem_t* sem1;
sem_t* sem2;
} sem_package;
void* thread_A (void *arg) {
sem_t* sem = (sem_t*) arg;
int random_sleep = (int) (500 + ((random()) / RAND_MAX) * 2000);
struct timespec sleep_time;
sleep_time.tv_sec = random_sleep / 1000;
sleep_time.tv_nsec = (random_sleep % 1000) * 1000000;
nanosleep(&sleep_time, NULL);
sem_post(sem); //unblock B
printf("\nA\n");
return NULL;
}
void* thread_B (void *arg) {
sem_package* pack = (sem_package*) arg;
int random_sleep = (int) (500 + ((random()) / RAND_MAX) * 2000);
struct timespec sleep_time;
sleep_time.tv_sec = random_sleep / 1000;
sleep_time.tv_nsec = (random_sleep % 1000) * 1000000;
nanosleep(&sleep_time, NULL);
sem_wait(pack->sem1); //wait for A
sem_post(pack->sem2); //unblock C
printf("\nB\n");
return NULL;
}
void* thread_C (void *arg) {
sem_package* pack = (sem_package*) arg;
int random_sleep = (int) (500 + ((random()) / RAND_MAX) * 2000);
struct timespec sleep_time;
sleep_time.tv_sec = random_sleep / 1000;
sleep_time.tv_nsec = (random_sleep % 1000) * 1000000;
nanosleep(&sleep_time, NULL);
sem_wait(pack->sem2); //wait for B
sem_post(pack->sem1); //unblock D
printf("\nC\n");
return NULL;
}
void* thread_D (void *arg) {
sem_t* sem = (sem_t*) arg;
int random_sleep = (int) (500 + ((random()) / RAND_MAX) * 2000);
struct timespec sleep_time;
sleep_time.tv_sec = random_sleep / 1000;
sleep_time.tv_nsec = (random_sleep % 1000) * 1000000;
nanosleep(&sleep_time, NULL);
sem_wait(sem); //wait for C
printf("\nD\n");
return NULL;
}
int main () {
srandom((unsigned int) time(NULL));
pthread_t threadA, threadB, threadC, threadD;
sem_t sem_A_B;
sem_t sem_C_D;
sem_t sem_B_C;
sem_init(&sem_A_B,0,0);
sem_init(&sem_C_D,0,0);
sem_init(&sem_B_C,0,0);
struct sem_package pack1;
pack1.sem1=&sem_A_B;
pack1.sem2=&sem_B_C;
struct sem_package pack2;
pack2.sem1=&sem_C_D;
pack2.sem2=&sem_B_C;
pthread_create(&threadA,NULL,thread_A,&sem_A_B);
pthread_create(&threadB,NULL,thread_B,&pack1);
pthread_create(&threadC,NULL,thread_C,&pack2);
pthread_create(&threadD,NULL,thread_D,&sem_C_D);
long m;
pthread_join(threadD, (void **) &m);
sem_destroy(&sem_A_B);
sem_destroy(&sem_B_C);
sem_destroy(&sem_C_D);
pthread_detach(threadA);
pthread_detach(threadB);
pthread_detach(threadC);
return 0;
}
【问题讨论】:
-
“有时它的顺序错误”。你怎么知道的?
-
@n.m.因为函数中的 printf 。是的,它是真的,可能会发生一个 sem_post 并且在它可能会失去轮到他并且另一个线程可能会因为该帖子而开始工作
-
一个,多线程的重要技巧是设计这样的事情不重要。 @n.m。已经指出要确保这样的事情是多么困难。最好不要费心尝试。
-
printf未以任何方式同步,输出可以按任何顺序显示。 -
在
sem_wait()之后和sem_post()之前打印加上fflush()会给你一个不错的机会。