c - pthread 根据用户输入中断线程循环

标签 c pthreads freeze

晚上好/早上好,

我正在尝试 pthread 的概念,并编写了一个小程序来测试它的各个部分。因此,我在主函数中创建了三个线程,然后第一个线程要求您输入。我希望线程按照 USER_INTERFACE_THREAD、PIC_COMMUNICATION_THREAD、然后 SEND_TO_SERVER_THREAD 的顺序执行,最后重复。我希望一次只运行一个线程,因此我使用了锁定方法:

#include <pthread.h>
#include <stdio.h>

#define TRUE (1)
#define FALSE (0)

void *Switch_statement();
void *Server_function();
void *User_choices();

pthread_t SEND_TO_SERVER_THREAD;
pthread_t PIC_COMMUNICATION_THREAD;
pthread_t USER_INTERFACE_THREAD;
pthread_mutex_t lock;
pthread_cond_t cond;

int userinput;
int UI_THREAD_RUNNING = TRUE;
int PIC_THREAD_RUNNING = FALSE;
int SERVER_THREAD_RUNNING = FALSE;

int main()
{
    pthread_create(&USER_INTERFACE_THREAD, NULL, User_choices, NULL);   
    pthread_create(&PIC_COMMUNICATION_THREAD, NULL, Switch_statement, NULL);
    pthread_create(&SEND_TO_SERVER_THREAD, NULL, Server_function, NULL);

    pthread_join(USER_INTERFACE_THREAD, NULL);
    pthread_join(PIC_COMMUNICATION_THREAD, NULL);
    pthread_join(SEND_TO_SERVER_THREAD, NULL);
}



void *Switch_statement()
{

    while(1)
    {
        while(UI_THREAD_RUNNING || SERVER_THREAD_RUNNING)
            pthread_cond_wait(&cond, &lock);

        pthread_mutex_lock(&lock);
        switch(userinput) 
        {
            case 0:         
                    printf("case0");
                    break;
            case 1:                                     //RETRIEVE ADC CASE
                    printf("case1");    
                    break;
            case 2:
                    printf("case2");
                    break;  
            case 3:                                     //RESET CASE
                    printf("case3");
                    break;                          //EXIT THE PROGRAM
            case 4:
                    printf("case4");
                    break;
            default:
                    printf("Your entry is not a valid option! Try again \n");                   
        }
        PIC_THREAD_RUNNING = FALSE;
        SERVER_THREAD_RUNNING = TRUE;
        pthread_mutex_unlock(&lock);
    }
}

void *Server_function()
{
    while(1)
    {
        while(PIC_THREAD_RUNNING || UI_THREAD_RUNNING)
            pthread_cond_wait(&cond, &lock);

        pthread_mutex_lock(&lock);
        printf("SERVER FUNCTION");

        SERVER_THREAD_RUNNING = FALSE;
        UI_THREAD_RUNNING = TRUE;
        pthread_mutex_unlock(&lock);
    }
}

void *User_choices()
{
    while (1)
    {
        while (PIC_THREAD_RUNNING || SERVER_THREAD_RUNNING)
            pthread_cond_wait(&cond, &lock);

        pthread_mutex_lock(&lock);
        printf("Type 0-4: ");
        scanf("%i", &userinput);
        printf("past scanf");
        UI_THREAD_RUNNING = FALSE;
        PIC_THREAD_RUNNING = TRUE;
        pthread_mutex_unlock(&lock);    
    }
}

在我的第二个线程中,您可以看到它检查用户输入。如果用户选择了属于默认情况的内容,我还希望将线程的顺序重置回 USER_INTERFACE_THREAD,而不转到 SERVER_THREAD。我还希望在用户单击 3 时终止所有三个线程并退出程序。那么我该如何实现呢? 我也没有使用 cond_signal 命令。那是一件坏事?如果是这样,我将如何使用它们?

编辑:修改后的问题仅关注我在发布后立即解决的一些问题

我添加了库并根据我所知道的正确初始化了我的变量。 所以这个问题一直持续下去,但有时我的程序会挂起。如果我使用 cond_wait 命令,它会立即挂起。如果我不这样做,就会引入竞争条件,并且如果线程 3 在线程 2 之前获取锁,它会再次挂起。我尝试使用广播语句,但出现了同样的问题。我应该使用两个单独的锁才能使其正常工作吗?

#include <pthread.h>
#include <stdio.h>
#include <stdbool.h>


void *Switch_statement();
void *Server_function();
void *User_choices();

pthread_t SEND_TO_SERVER_THREAD;
pthread_t PIC_COMMUNICATION_THREAD;
pthread_t USER_INTERFACE_THREAD;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int userinput;
int UI_THREAD_RUNNING = true;
int PIC_THREAD_RUNNING = false;
int SERVER_THREAD_RUNNING = false;

int main()
{
    pthread_create(&USER_INTERFACE_THREAD, NULL, User_choices, NULL);   
    pthread_create(&PIC_COMMUNICATION_THREAD, NULL, Switch_statement, NULL);
    pthread_create(&SEND_TO_SERVER_THREAD, NULL, Server_function, NULL);

    pthread_join(USER_INTERFACE_THREAD, NULL);
    pthread_join(PIC_COMMUNICATION_THREAD, NULL);
    pthread_join(SEND_TO_SERVER_THREAD, NULL);
}



void *Switch_statement()
{

    while(1)
    {
        while(UI_THREAD_RUNNING || SERVER_THREAD_RUNNING)
            pthread_cond_wait(&cond, &lock);

        pthread_mutex_lock(&lock);
        switch(userinput) 
        {
            case 0:         
                    printf("case0");
                    break;
            case 1:                                     //RETRIEVE ADC CASE
                    printf("case1");    
                    break;
            case 2:
                    printf("case2");
                    break;  
            case 3:                                     //RESET CASE
                    printf("case3");
                    break;                          //EXIT THE PROGRAM
            case 4:
                    printf("case4");
                    break;
            default:
                    printf("Your entry is not a valid option! Try again \n");                   
        }
        PIC_THREAD_RUNNING = false;
        SERVER_THREAD_RUNNING = false;
    pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&lock);
    }
}

void *Server_function()
{
    while(1)
    {
        while(PIC_THREAD_RUNNING || UI_THREAD_RUNNING)
            pthread_cond_wait(&cond, &lock);

        pthread_mutex_lock(&lock);
        printf("SERVER FUNCTION");

        SERVER_THREAD_RUNNING = false;
        UI_THREAD_RUNNING = true;
    pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&lock);
    }
}

void *User_choices()
{
    while (1)
    {
        while (PIC_THREAD_RUNNING || SERVER_THREAD_RUNNING)
            pthread_cond_wait(&cond, &lock);

        pthread_mutex_lock(&lock);
        printf("Type 0-4: ");
        scanf("%i", &userinput);
        printf("past scanf");
        UI_THREAD_RUNNING = false;
        PIC_THREAD_RUNNING = true;
    pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&lock);    
    }
}

最佳答案

感谢 @WhosCraig 提供的链接,我重新编写了代码,它似乎可以正常工作:

#include <pthread.h>
#include <stdio.h>
#include <stdbool.h>


void *Switch_statement();
void *Server_function();
void *User_choices();

pthread_t SEND_TO_SERVER_THREAD;
pthread_t PIC_COMMUNICATION_THREAD;
pthread_t USER_INTERFACE_THREAD;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t CONDITION_UI = PTHREAD_COND_INITIALIZER;
pthread_cond_t CONDITION_PIC = PTHREAD_COND_INITIALIZER;
pthread_cond_t CONDITION_SERVER = PTHREAD_COND_INITIALIZER;

int userinput;
int UI_THREAD_RUNNING = true;
int PIC_THREAD_RUNNING = false;
int SERVER_THREAD_RUNNING = false;

int main()
{
    pthread_create(&USER_INTERFACE_THREAD, NULL, User_choices, NULL);   
    pthread_create(&PIC_COMMUNICATION_THREAD, NULL, Switch_statement, NULL);
    pthread_create(&SEND_TO_SERVER_THREAD, NULL, Server_function, NULL);

    pthread_join(USER_INTERFACE_THREAD, NULL);
    pthread_join(PIC_COMMUNICATION_THREAD, NULL);
    pthread_join(SEND_TO_SERVER_THREAD, NULL);
}



void *Switch_statement()
{

    while(1)
    {
    pthread_mutex_lock(&lock);
        while(UI_THREAD_RUNNING || SERVER_THREAD_RUNNING)
            pthread_cond_wait(&CONDITION_PIC, &lock);

        pthread_mutex_unlock(&lock);

        switch(userinput) 
        {
            case 0:         
                    printf("case0");
                    break;
            case 1:                                     //RETRIEVE ADC CASE
                    printf("case1");    
                    break;
            case 2:
                    printf("case2");
                    break;  
            case 3:                                     //RESET CASE
                    printf("case3");
                    break;                          //EXIT THE PROGRAM
            case 4:
                    printf("case4");
                    break;
            default:
                    printf("Your entry is not a valid option! Try again \n");                   
        }
    pthread_mutex_lock(&lock);
        PIC_THREAD_RUNNING = false;
        SERVER_THREAD_RUNNING = true;
    pthread_cond_signal(&CONDITION_SERVER);
        pthread_mutex_unlock(&lock);
    }
}

void *Server_function()
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        while(PIC_THREAD_RUNNING || UI_THREAD_RUNNING)
            pthread_cond_wait(&CONDITION_SERVER, &lock);

        pthread_mutex_unlock(&lock);
        printf("SERVER FUNCTION");

    pthread_mutex_lock(&lock);
        SERVER_THREAD_RUNNING = false;
        UI_THREAD_RUNNING = true;
    pthread_cond_signal(&CONDITION_UI);
        pthread_mutex_unlock(&lock);
    }
}

void *User_choices()
{
    while (1)
    {
    pthread_mutex_lock(&lock);
        while (PIC_THREAD_RUNNING || SERVER_THREAD_RUNNING)
            pthread_cond_wait(&CONDITION_UI, &lock);

        pthread_mutex_unlock(&lock);
        printf("Type 0-4: ");
        scanf("%i", &userinput);
    pthread_mutex_lock(&lock);
        UI_THREAD_RUNNING = false;
        PIC_THREAD_RUNNING = true;
    pthread_cond_signal(&CONDITION_PIC);
        pthread_mutex_unlock(&lock);    
    }
}

关于c - pthread 根据用户输入中断线程循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36632624/

相关文章:

java - Mac OS X 10.9.4 上的小程序。卡在 CAccessible.selectionChanged()

css - @font-face 带有多个字体大小的 css 声明会使 Firefox 缓慢爬行

c - 在 gtk 窗口中流式传输 libuvc 代码的过程是什么?

linux - pthread_self() 和 gettid() 有什么区别?我应该使用哪一个?

C - 使用 pthread 重现两个线程之间全局变量的同步问题

c++ - Pthread_create 在 C++ 中导致段错误

hadoop - Hive终端在使用INSERT命令插入数据时挂起

c - 如何将字符串转换为 int 或 float 类型?

c - 是什么导致了这个段错误?

c++ - 带有 C 接口(interface)的 Objective C 库