[英]How to execute one thread after another with pthreads?
我正在为使用 5 个线程的嵌入式操作系统开发模拟器。 一个充当调度程序线程,另外 4 个充当工作线程。 操作顺序始终相同:调度程序在所有其他线程之间执行,然后继续激活下一个应该为 go 的线程,如下所示: SchThread Thread1 SchThread Thread2 SchThread Thread3 SchThread Thread4 SchThread Thread1...
等等。
这是目前在 Windows 中完成的一些不良做法,我的任务是将其切换到 pthreads 实现。 我知道这不是线程应该如何工作,因为工作负载是完全顺序的,但模拟器依赖于提到的 5 个线程。
我的问题是:我应该如何实现这种行为? 互斥量或条件是否足够? 我应该使用障碍吗? 也许来自调度程序的信号会唤醒工作线程?
我见过这样的帖子(按特定顺序执行 pthreads) ,它适用于 2 个线程,但我尝试将数量增加到 5 失败了。使用pthread_cond_
是解决此问题的好方法还是我对焦不对?
我也尝试过使用互斥锁或信号量进行同步,但没有成功。 我想到了一个管理转弯的共享变量,但我一直无法使其正常工作。
这是一种意见,因为解决您的问题的方法不止一种。
我将使用一个共享的全局变量currentThread
,其值标识应该运行哪个线程,并且我将使用一个条件变量让线程在currentThread
更改时相互通知。
抱歉,我现在没有时间写示例,但您可以在pthread_cond_t
、 pthread_cond_wait(...)
和pthread_cond_broadcast(...)
的手册页中找到示例
几天来我一直在考虑问这个问题,在我发布问题的那一天,我找到了解决这个问题的可能方法。
继续解释问题中链接的答案,解决方案如下所示:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h> /* sleep */
#define MS100 100000
#define HALFS 500000
pthread_mutex_t m_sch;
pthread_cond_t SCH_GO;
pthread_cond_t THREAD2_GO;
pthread_cond_t THREAD3_GO;
unsigned turno = 1;
/* get next turn */
int sig_turno() {
static int anterior = 0;
int ret;
switch (anterior) {
case 2:
ret = 3;
break;
case 3:
ret = 2;
break;
default: /* first time */
ret = 2;
break;
}
anterior = ret;
return ret;
}
int sch_ret = 0;
void *sch(void *arg) {
int turno_local;
while (1) {
pthread_mutex_lock(&m_sch);
while (turno != 1) {
pthread_cond_wait(&SCH_GO, &m_sch);
}
printf("[THREAD SCH]\n");
usleep(MS100);
turno_local = sig_turno();
turno = turno_local;
switch (turno_local) {
case 2:
pthread_cond_signal(&THREAD2_GO);
break;
case 3:
pthread_cond_signal(&THREAD3_GO);
break;
default:
printf("error.\n");
break;
}
pthread_mutex_unlock(&m_sch);
}
sch_ret = 1;
return &sch_ret;
}
int thread2_ret = 0;
void *thread2(void *arg) {
while (1) {
pthread_mutex_lock(&m_sch);
while (turno != 2) {
pthread_cond_wait(&THREAD2_GO, &m_sch);
}
printf("[THREAD 2]\n");
usleep(HALFS);
turno = 1;
pthread_cond_signal(&SCH_GO);
pthread_mutex_unlock(&m_sch);
}
thread2_ret = 2;
return &thread2_ret;
}
int thread3_ret = 0;
void *thread3(void *arg) {
while (1) {
pthread_mutex_lock(&m_sch);
while (turno != 3) {
pthread_cond_wait(&THREAD3_GO, &m_sch);
}
printf("[THREAD 3]\n");
usleep(HALFS);
turno = 1;
pthread_cond_signal(&SCH_GO);
pthread_mutex_unlock(&m_sch);
}
thread3_ret = 3;
return &thread3_ret;
}
int main() {
void *ret;
pthread_t thread_sch, thread_2, thread_3;
pthread_cond_init(&SCH_GO, NULL);
pthread_cond_init(&THREAD2_GO, NULL);
pthread_cond_init(&THREAD3_GO, NULL);
pthread_mutex_init(&m_sch, NULL);
pthread_create(&thread_sch, NULL, sch, NULL);
usleep(MS100);
pthread_create(&thread_2, NULL, thread2, NULL);
pthread_create(&thread_3, NULL, thread3, NULL);
pthread_join(thread_sch, &ret);
pthread_join(thread_2, &ret);
pthread_join(thread_3, &ret);
printf("main() ending\n");
return 0;
}
其中sch
是调度程序的线程。
这可以扩展到更多线程并按预期工作,即使它只是一个草稿。 我一直无法仅使用互斥体获得类似的行为,因此条件是 go。
我确实接受对此解决方案的批评和改进,我真的不知道它是否正确/良好做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.