pthread根据用户输入打破线程周期

时间:2016-04-14 19:48:40

标签: c pthreads hang

晚上好/早上好,

我正在尝试使用pthreads的概念,并编写了一个小程序来测试它的各个部分。所以,我在main函数中创建了三个线程,然后第一个线程要求您输入。我希望线程按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);    
    }
}

1 个答案:

答案 0 :(得分:-1)

感谢@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);    
    }
}