good evening/morning,
I'm experimenting with the concepts of pthreads and have a small program written to test various pieces of it. So, I have three threads created in the main function, and then the first thread asks you for input. I want the threads to execute in the order of USER_INTERFACE_THREAD, PIC_COMMUNICATION_THREAD, then SEND_TO_SERVER_THREAD, and finally repeat. I want only one thread running at a time, so I use a lock method:
#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);
}
}
In my second thread, you can see that it checks the user input. I would also like the order of the threads to be reset back to the USER_INTERFACE_THREAD without going to the SERVER_THREAD if the user picks something that falls under the default case. I would also like all three threads to be terminated and the program to exit if the user clicks 3. So how can I implement this? I'm also not using an cond_signal commands. is that a bad thing? If so, how would I use these?
EDIT: Revised question to only focus on the issues I still have since I figured some out right after posting
I added the library and initialized my variables properly from what I know. So this issue keeps going on off, but sometimes my program hangs. If i use the cond_wait command, it hangs immediately. If i don't, a race condition is introduced and if thread 3 grabs the lock before thread 2, it hangs again. I tried to use a broadcast statement, but the same issue occurs. Am i supposed to use two separate locks to get this to work properly?
#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);
}
}