繁体   English   中英

如何用pthreads一个线程一个线程执行?

[英]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_tpthread_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM