c program compiler gcc
I have 3 files. main.c stop_watch.h and stop_watch.c
This program does work. I call start_stopwatch. And it will callback in main.c timeout_cb() after the time has expired. I also run this in a seperate thread, as I don't want to block in main, as I will have other code I need to run.
1) The seconds in g_start_timer always gives rubbish. I thought I might have solved this by creating the structure on the heap. Is there anyway I can solve this. I was thinking of creating the seconds element on the heap. But think this is over kill
2) This program works fine, but if I comment out the line in main printf("=== timeout_cb: %p\n", timeout_cb); it will stack dump.
3) when is the best time to free the memory. I was freeing it in main. But I am worried if the memory is freed before the thread has finished. That could cause a very unexpected result. I am thinking I could use thread_join() as free the memory after this call. However, I would need to return the thead_id that is created in the stop_watch.c, is there a way to return the thread_id that is created in stop_watch.c
Many thanks for any suggestions,
main.c
/* main.c */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "stop_watch.h"
/* call this when the time expires */
void timeout_cb()
{
printf("=== your time is up run some job here ===\n");
}
int main()
{
struct data_struct *g_data_struct =
(struct data_struct*) calloc(1, sizeof(*g_data_struct));
if(!g_data_struct)
{
printf("=== failed to allocate memory ===\n");
return 0;
}
g_data_struct->seconds = 3;
g_data_struct->func_ptr = timeout_cb;
// printf("=== timeout_cb: %p\n", timeout_cb);
start_stopwatch(g_data_struct);
// free(g_data_struct);
printf("=== End of Program - all threads in ===\n");
pthread_exit(NULL);
return 0;
}
stop_watch.h
/* stop_watch.h */
struct data_struct
{
int seconds;
void (*func_ptr)(void);
};
void start_stopwatch(struct data_struct *g_data_struct);
stop_watch.c
#include <stdio.h>
#include <pthread.h>
#include "stop_watch.h"
static void* g_start_timer(void *args)
{
void (*function_pointer)();
int seconds = ((struct data_struct*) args)->seconds;
function_pointer = ((struct data_struct*) args)->func_ptr;
printf("=== go to sleep for %d\n", seconds);
sleep(seconds);
(void) (*function_pointer)();
pthread_exit(NULL);
return 0;
}
void start_stopwatch(struct data_struct *g_data_struct)
{
pthread_t thread_id;
int rc;
int seconds = g_data_struct->seconds;
printf("=== start_stopwatch(): %d\n", seconds);
rc = pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);
if(rc)
printf("=== Failed to create thread\n");
}
In simple language, If a reference of a function is passed to another function as an argument to call it, then it will be called as a Callback function. In C, a callback function is a function that is called through a function pointer.
One pattern for performing long-running tasks without blocking the main thread is callbacks. By using callbacks, you can start long-running tasks on a background thread. When the task completes, the callback, supplied as an argument, is called to inform your code of the result on the main thread.
A callback function is a function that is passed as an argument to another function, to be “called back” at a later time. A function that accepts other functions as arguments is called a higher-order function, which contains the logic for when the callback function gets executed.
A callback function is a function that occurs after some event has occurred. The reference in memory to the callback function is usually passed to another function. This allows the other function to execute the callback when it has completed its duties by using the language-specific syntax for executing a function.
The line in start_stopwatch()
:
rc = pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);
should be:
rc = pthread_create(&thread_id, NULL, g_start_timer, (void *) g_data_struct);
In the first case, you're passing a "pointer to a pointer" when you really just want to pass the pointer as the thread argument.
As far as when to free the data, there are many options. If you will always pass the thread data in a heap allocated block, then the g_start_timer()
thread proc can free it when it's finished pulling the data out. Note that if you do this, then part of the protocol for starting the thread is that the thread argument block must be heap allocated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With