I have a robot that I am controlling through a specific library with C.
I need a thread that checks if a button is pressed, and if it is, the program exits.
This check should happen separated from the main thread, so that I can run the robot movement code along with the button check code.
I've made a small PoC but it's not working: the program flow halts and the button check is executed indefinitely.
Here is the code. If some variables/functions are missing in this snippet, don't worry, they are there in the actual code.
void *brick_controller(void *vargp){
printf("Second thread is working!\n");
uint8_t button_buffer;
while(true)
{
size_t result = ev3_read_keys(&button_buffer);
//printf("ass %d\n", buf);
if(button_buffer == 32){
exit(666);
}
}
}
int main(int argc, char** argv)
{
printf( "Waiting the EV3 brick online...\n" );
if ( ev3_init() < 1 ) return ( 1 );
printf( "*** ( EV3 ) Hello! ASS ***\n" );
ev3_sensor_init();
ev3_tacho_init();
app_alive = app_init();
if (app_alive == 0)
{
/*int distance = 250;
if (argc == 1)
{}
else if (argc == 2)
{
default_speed = atoi(argv[1]);
}
else if (argc == 3)
{
default_speed = atoi(argv[1]);
distance = atoi(argv[2]);
}
else {
printf("Too many arguments!\n");
return 0;
}
printf("Speed:%d\n"
"Distance:%d\n", default_speed, distance);
drive(default_speed, distance);
*/
pthread_create(&brick_controller_thread, NULL, *brick_controller, NULL);
pthread_join(brick_controller_thread, NULL);
int i = 0;
while(i < 200){ // This never executes :(
i++;
printf("All is running! %d\n", i);
}
} else {
printf("App initialization failed! Error code: %d\n", app_alive);
return 2;
}
ev3_uninit();
return 0;
According to the man page:
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then
pthread_join() returns immediately. The thread specified by thread
must be joinable.
pthread_join waits for the thread to terminate, which never will.
Related
Removing a printf statement affects the value of "i" in the loop where the program creates the child threads. I've tried printing a non-formatted string, and it breaks the program. Moving the printf above pthread_create() causes the same result. However, printing any formatted string after creating a thread will "fix" the program. Does anyone know what I've done wrong?
#include <stdio.h>
#include <pthread.h>
#define FALSE 0
#define TRUE !FALSE
pthread_mutex_t mutex;
pthread_cond_t cond1;
pthread_cond_t cond2;
int flag1 = FALSE;
int flag2 = FALSE;
void* someFunction(void* arg);
void anotherFunction(int threadNumber);
int main(int argc, char* argv[])
{
pthread_t threads[6];
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond1, NULL);
pthread_cond_init(&cond2, NULL);
for (int i = 0; i < 6; i++)
{
// moving the printf to here will cause the program to hang
pthread_create(&threads[i], NULL, &someFunction, &i);
// not printing a formatted string here will cause the program to hang
printf("Thread %d created\n", i);
}
pthread_mutex_lock(&mutex);
for (int i = 0; i < 6; i++)
{
flag1 = TRUE;
// go to child thread
pthread_cond_signal(&cond1);
// wait for child thread to change flag2
while (flag2 == FALSE)
{
pthread_cond_wait(&cond2, &mutex);
}
flag2 = FALSE;
pthread_mutex_unlock(&mutex);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond1);
pthread_cond_destroy(&cond2);
return 0;
}
void* someFunction(void* arg)
{
int threadNumber = *(int*)arg;
pthread_mutex_lock(&mutex);
// wait for parent thread to change flag1
while (flag1 == FALSE)
{
pthread_cond_wait(&cond1, &mutex);
}
anotherFunction(threadNumber);
flag2 = TRUE;
// go back to parent thread
pthread_cond_signal(&cond2);
pthread_mutex_unlock(&mutex);
return NULL;
}
void anotherFunction(int threadNumber)
{
if (threadNumber == 0)
{
printf("I'm thread %d!\n", threadNumber);
}
else if (threadNumber == 1)
{
printf("I'm thread %d!\n", threadNumber);
}
else if (threadNumber == 2)
{
printf("I'm thread %d!\n", threadNumber);
}
else if (threadNumber == 3)
{
printf("I'm thread %d!\n", threadNumber);
}
else if (threadNumber == 4)
{
printf("I'm thread %d!\n", threadNumber);
}
else if (threadNumber == 5)
{
printf("I'm thread %d!\n", threadNumber);
}
}
This is the output when printing a formatted string.
Thread 0 created
Thread 1 created
Thread 2 created
Thread 3 created
Thread 4 created
Thread 5 created
I'm thread 0!
I'm thread 1!
I'm thread 2!
I'm thread 3!
I'm thread 4!
I'm thread 5!
This is the output when removing the printf
I'm thread 1!
I'm thread 2!
I'm thread 3!
I'm thread 4!
I'm thread 5!
The program just hangs after printing "I'm thread 5!".
EDIT: Thanks for the replies guys! Here is the solution
for (int i = 0; i < 6; i++)
{
int* copy = malloc(sizeof(int));
*copy = i;
// moving the printf to here will cause the program to hang
pthread_create(&threads[i], NULL, &someFunction, copy);
// not printing a formatted string here will cause the program to hang
printf("Thread %d created\n", i);
}
Here you pass the address of a local variable i to the thread functions. This variable goes out of scope at least when the for loop ends (or maybe even at the end of each iteration). This means every access to the variable by the threads after the end of the loop (or after the end of the loop iteration) is undefined behavior.
for (int i = 0; i < 6; i++)
{
// moving the printf to here will cause the program to hang
pthread_create(&threads[i], NULL, &someFunction, &i);
// not printing a formatted string here will cause the program to hang
// printf("Thread %d created\n", i);
}
Your program will report this error when you compile the program with GCC using options -fsanitize=address -fsanitize=undefined.
Even if you fix the scope of the variable, e.g. by moving it into function main's scope, you pass the address of the same variable to all threads, so it is undefined which value (0..6) every thread may see. If the thread creation is faster than actually starting the thread, all threads might see the same value 6.
(As noted in a comment, you might even see other values because of the data race. If the access to the variable is atomic on your platform or if the loop modifies only the least significant byte as in this example, you will typically get one of the values 0..6.)
Thanks for the replies guys! The solution was to dynamically allocate some memory for a copy of i
for (int i = 0; i < 6; i++)
{
int* copy = malloc(sizeof(int));
*copy = i;
// moving the printf to here will cause the program to hang
pthread_create(&threads[i], NULL, &someFunction, copy);
// not printing a formatted string here will cause the program to hang
printf("Thread %d created\n", i);
}
I'm working on an assignment in C aimed at using a pipe to pass variables between two processes. Both processes must be forked from the parent, and they must run concurrently to pass one character at a time (sort of demonstrated below).
The issue I'm having is that the fork()ed processes are not running concurrently. The sender seems to go first, and after running for ~26 seconds the receiver begins. Here is the code I have written:
#include <stdio.h>
int ret;
int pipearray[2];
char buffer[26];
void mysender();
void myreceiver();
int main()
{
int pid = 0;
int i = 0;
ret = pipe(pipearray);
while (i < 2) {
pid = fork();
if ( pid == 0 && i == 0 ) /* child process execution (receiver) */
{
myreceiver();
printf("Your receiver is done\n");
exit(0);
}
else if ( pid == 0 && i == 1 ) /* now executes sender */
{
mysender();
printf("Your sender is done\n");
exit(0);
}
++i;
}
close(pipearray[0]);
close(pipearray[1]);
sleep(30);
printf("Parent function has finished.\n");
return 0;
}
void mysender()
{
char c;
int index = 90;
close(pipearray[0]);
while (index > 64) /* loop for all values of A-Z in ASCII */
{
c = (char) index;
open(pipearray[1]);
write(pipearray[1], c, sizeof(c)); /* Sends letter to pipe */
--index;
sleep(1);
}
close(pipearray[1]);
}
void myreceiver()
{
int index = 0;
close(pipearray[1]);
while(buffer != 'A') /*loop runs until 'A' is handled */
{
sleep(1);
open(pipearray[0]);
read(pipearray[0], buffer, 1);
printf("%s", &buffer);
index++;
if ( index == 26 ) { break; }
}
close(pipearray[0]);
}
Expected Result:
ZYXWVUTSRQPONMLKJIHGFEDCBA
Your sender is done
Your receiver is done
The parent function has finished.
My result:
Your sender is done
The parent function has finished.
Your receiver is done
I'm very new to C programming but I've been banging away at this for a while. Any tips to why these might not be running simultaneously would be very appreciated.
There is many errors in your code. Don't try to open the pipe after fork, it is already open and has no name. Write should use the address of c. Read must read into the right place. A flush must be done after write to stdout. Your conditional must be slightly modified to be guaranteed correct. The parent process must wait its children. Here is the modified code :
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int ret;
int pipearray[2];
char buffer[26];
void mysender();
void myreceiver();
int main()
{
int pid = 0;
int i = 0;
ret = pipe(pipearray);
while (i < 2) {
pid = fork();
if ( pid == 0 && i == 0 ) /* child process execution (receiver) */
{
myreceiver();
printf("Your receiver is done\n");
exit(0);
}
else if ( pid == 0 && i == 1 ) /* now executes sender */
{
mysender();
printf("Your sender is done\n");
exit(0);
}
++i;
}
close(pipearray[0]);
close(pipearray[1]);
// Don't sleep, but wait until the end of the two children
wait(NULL);
wait(NULL);
// sleep(30);
printf("Parent function has finished.\n");
return 0;
}
void mysender()
{
char c;
int index = 90;
close(pipearray[0]);
while (index > 64) /* loop for all values of A-Z in ASCII */
{
c = (char) index;
// try to open a anonymous pipe is a non-sense
// open(pipearray[1]);
// Send a buffer by its address
write(pipearray[1], &c, sizeof(c)); /* Sends letter to pipe */
--index;
sleep(1);
}
close(pipearray[1]);
}
void myreceiver()
{
int index = 0;
close(pipearray[1]);
// Ensure condition is entered first
buffer[index] = 0;
// This is not the best condition ever, but ok.
while(buffer[index] != 'A') /*loop runs until 'A' is handled */
{
sleep(1);
// Don't open an anonymous pipe
// open(pipearray[0]);
// Read at the right position
read(pipearray[0], buffer+index, 1);
// print and flush, could also be printf("%s"...); flush(stdout);
printf("%s\n", buffer);
index++;
if ( index == 26 ) { break; }
}
close(pipearray[0]);
}
Now, consider to remove the sleeps in the reader, as it will be synchronized with the writes such that no read is possible if no write has been done. Alos consider to read more that one byte, because there is no concept of message, so that you can read as much byte you consider necessary to read, and as usual it is better to try reading a bunch of bytes when you can.
I've wrote the following program. I expect that this function print 1, 2 sequentially but
the program waits some time(for example 10 sec) and then prints all of the result.
here is the code:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
void *thread_function(void *arg);
char message[] = "Hello World";
int run_now = 1;
int main()
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0)
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
int print_count1 = 0;
while(print_count1++ < 20)
{
if (run_now == 1)
{
printf("1");
run_now = 2;
}
else
{
sleep(1);
}
}
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined. \n");
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg)
{
int print_count2 = 0;
while(print_count2++ < 20)
{
if (run_now == 2)
{
printf("2");
run_now = 1;
}
else
{
sleep(1);
}
}
}
i expect to 1, 2 be printed every 1 seconds, but program is waiting some times and then prints all of the string entirely. can anybody tell me what's the reason?
int run_now is accessed concurrently and therefore its access needs to be protected.
To do so use a mutex for example:
...
int run_now = 1;
pthtread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
...
while(print_count1++ < 20)
{
pthread_mutex_lock(&mutex);
int run_now_equals_1 = (run_now == 1);
if (run_now_equals_1)
{
printf("1");
run_now = 2;
}
pthread_mutex_unlock(&mutex);
if (!run_now_equals_1)
{
sleep(1);
}
}
...
}
void *thread_function(void *arg)
{
int print_count2 = 0;
while(print_count2++ < 20)
{
pthread_mutex_lock(&mutex);
int run_now_equals_2 = (run_now == 2);
if (run_now_equals_2)
{
printf("2");
run_now = 1;
}
pthread_mutex_unlock(&mutex);
if (!run_now_equals_2)
{
sleep(1);
}
}
}
Well, there are a few problems with your program. First, printf may buffer things internally, so you won't see them. This is probably what you refer to. You need to fflush stdout after each printf. The more serious problem is that your program is wrong, as it uses a non-atomic, non-volatile variable for communication.
In your thread_function, the compiler is free to move the load of run_now out of the loop and only work with a register copy, hence the loop won't ever notice that another thread changed the value in memory. You should always use atomic intrinsics to access shared variables like this.
Use fprintf(stderr,"...") instead of printf, or add a fflush(stdout) after each printf.
This is because stout is flushed only when OS decides to flush it, while stderr is flushed as soon as fprintf is called.
I have a process with 2 threads. if one of the 2 threads is done executing his instructions, then the other should stop too. And the process should end. How to check if one of the threads has done executing the instructions? This is the code that i have written so far.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int read = 0;
int timeLeft = 0;
void *readFromFile(void *myFile){
char *theFile;
theFile = (char*) myFile;
char question[100];
char answer[100];
FILE *file = fopen(theFile, "r");
if(file != NULL){
while(fgets(question,sizeof question,file) != NULL){
fputs(question, stdout);
scanf("%s", &answer);
}
read = 1;
fclose(file);
printf("Done with questions!\n");
pthread_exit(
}
else{
perror(theFile);
}
}
void displayTimeLeft(void *arg){
int *time;
time = (int*) arg;
int i;
for(i = time; i >= 0; i -= 60){
if( i / 60 != 0){
printf("You have %d %s left.\n", i/60,(i/60>1)?"minutes":"minute");
sleep(60);
}
else{
timeLeft = 1;
printf("The time is over \n");
break;
}
}
}
int main(){
pthread_t thread1;
pthread_t thread2;
char *file = "/home/osystems01/laura/test";
int *time = 180;
int ret1;
int ret2;
ret1 = pthread_create(&thread1, NULL, readFromFile,&file);
ret2 = pthread_create(&thread2, NULL, displayTimeLeft,&time);
printf("Main function after pthread_create");
while(1){
//pthread_join(thread1,NULL);
//pthread_join(thread2,NULL);
if(read == 1){
pthread_cancel(thread2);
pthread_cancel(thread1);
break;
}
else if(timeLeft == 0){
pthread_cancel(thread1);
pthread_cancel(thread2);
break;
}
}
printf("After the while loop!\n");
return 0;
}
You can declare a global flag variable and set it to false initially.
Whenever a thread reaches its last statement it sets the flag to true. And whenever a thread starts executing it will first check the flag value, if it false i.e. no other thread has updated it continues execution else returns from the function
First of all you might want to read the pthread_cancel manual page (and the manual pages for the associated pthread_setcancelstate and pthread_setcanceltype functions). The first link contains a nice example.
Another solution is to have e.g. a set of global variables that the threads checks from time to time to see if they should exit or if another thread have exited.
The problem with using e.g. pthread_cancel is that the thread is terminated without letting you clean up after your self easily, which can lead to resource leaks. Read about pthread_key_create about one way to overcome this.
gcc 4.6.0 c89
I am just experimenting with using pthread_exit and pthread_join.
The only thing I notice with the pthread_exit it that it didn't display the print message before main returned. However, pthread_join did exactly that.
I would have thought the print statement should have been displayed. If not does that mean that main has not terminated correctly in using the pthread_exit?
Many thanks for any suggestions,
My source code snippet source.c file:
void* process_events(void)
{
app_running = TRUE;
int counter = 0;
while(app_running) {
#define TIMEOUT 3000000
printf("Sleeping.....\n");
usleep(TIMEOUT);
if(counter++ == 2) {
app_running = FALSE;
}
}
printf("Finished process events\n");
return NULL;
}
Source code snippet main.c file:
int main(void)
{
pthread_t th_id = 0;
int th_rc = 0;
th_rc = pthread_create(&th_id, NULL, (void*)process_events, NULL);
if(th_rc == -1) {
fprintf(stderr, "Cannot create thread [ %s ]\n", strerror(errno));
return -1;
}
/*
* Test with pthread_exit and pthread_join
*/
/* pthread_exit(NULL); */
if(pthread_join(th_id, NULL) == -1) {
fprintf(stderr, "Failed to join thread [ %s ]", strerror(errno));
return -1;
}
printf("Program Terminated\n");
return 0;
}
What you're seeing is expected. pthread_exit never returns. It stops the thread that calls it immediately (and then runs the clean-up handlers if any, and then potentially thread-specific data destructors).
Nothing in main after pthread_exit will ever run.