First of all, let me apologize as I can see that similar questions have been posted quite a few times in the past. However, as I am very unfamiliar with C, I need help confirming this.
I am trying to ensure that my program leaves a clean gpio if I interrupt it with CTRL+C. Easily done in python or java, but C proves to be a harder nut to crack for me, as I was led to believe that no try-catch-finally exists in C. Googling it, I found what I think may be the solution, but unexperienced as I am, I'm not sure it's done properly. Here is my code:
#include <stdio.h>
#include <wiringPi.h>
#include <signal.h>
void CleanGPIO() {
pinMode(1,INPUT);
}
int main()
{
wiringPiSetup();
signal(SIGINT, CleanGPIO);
pinMode(1, PWM_OUTPUT);
for (int i = 0; i < 1024; ++i) {
pwmWrite(1, i);
delay(1);
}
for (int i = 1023; i >= 0; --i) {
pwmWrite(1, i);
delay(1);
}
pinMode(1,INPUT);
return 0;
}
I have tested it and it works as intended (pin 1 is set as IN after I interrupt it with CTRL+C), but I'm concerned if this is the safe way to do it, and if there is a better solution available.
calling any function which is not speficied as signal-safe from a signal handler is undefined behaviour. I suppose there is no such guarantee about pinMode.
The proper way would be to set a volatile int flag that you periodically check in your main loop.
volatile int terminating = 0;
void terminate(int sign) {
signal(SIGINT, SIG_DFL);
terminating = 1;
}
int main() {
for (...) {
if (terminating) {
// cleanup
exit(1);
}
}
}
the call to signal inside the handler is to allow force terminating the program with a second ctrl+c in case proper clenup takes too long or is stuck for any reason.
Your solution is nearly right. You should also call exit in order to force the program to terminate (assuming you want to terminate immediately). The exit call takes a parameter which is the exit status to return to the caller (e.g., the shell). This should be non-zero for abnormal termination.
So, it should be:
void CleanGPIO() {
pinMode(1,INPUT);
exit(1);
}
If you don't want to exit from the handler but from main in a more controlled fashion you can set a flag instead and check the flag value inside the loops.
Related
I have a simple program using signal with the user's handlers.
#include <signal.h>
#include <stdio.h>
#include <zconf.h>
int x = 0;
int i = 3;
void catcher3(int signum) {
i = 1;
}
void catcher2(int signum) {
// Stuck in infinity loop here.
// Happens even with i == 0
if (i != 0) {
x = 5;
}
}
void catcher1(int signum) {
printf("i = %d\n", i);
i--;
if (i == 0) {
signal(SIGFPE, catcher2);
signal(SIGTERM, catcher3);
}
}
int main() {
signal(SIGFPE, catcher1);
x = 10 / x;
printf("Goodbye");
}
While I expect it to print:
3
2
1
Goodbye
It actually prints:
3
2
1
# Infinity loop within catcher2
My questions are:
On running a user handler like catcher1, to which point the code returns after the handler's execution? I would expect it continue the execution but it re-runs the signal handler.
What causes the infinity loop?
How to fix it?
Why sending SIGTERM won't print "Goodbye"? (kill -s TERM <pid>)
As pointed out by AProgrammer, the program doesn't necessarily read x after returning from the handler, even if x is marked volatile (which it should be anyway). This is because the execution continues to the offending instruction. The read from memory and the actual division could be separate instructions.
To get around this you will have to continue the execution to a point before x was read from memory.
You can modify your program as follows -
#include <csetjmp>
jmp_buf fpe;
volatile int x = 0; // Notice the volatile
volatile int i = 3;
void catcher2(int signum) {
if (i != 0) {
x = 5;
longjump(fpe, 1);
}
}
int main() {
signal(SIGFPE, catcher1);
setjump(fpe);
x = 10 / x;
printf("Goodbye");
}
Rest of the functions can remain the same.
You should also not be using printf from the signal handler. Instead use write directly to print debug messages as -
write(1, "SIGNAL\n", sizeof("SIGNAL\n"));
The handling of signals is complex and full of implementation defined, unspecified and undefined behavior. If you want to be portable, there is in fact very few things that you can do. Mostly reading and writing volatile sig_atomic_t and calling _Exit. Depending on the signal number, it is often undefined if you leave the signal handler in another way than calling _Exit.
In your case, I think FPE is one of those signals for which leaving normally the signal handler is UB. The best I can see is restarting the machine instruction which triggered the signal. Few architectures, and last I looked x86 was not one of them, provide a way to do 10/x without loading x in a register; that means that restarting the instruction will always restart the signal, even if you modify x and x us a volatile sig_atomtic_t.
Usually longjmp is also able to leave signal handler. #Bodo confirmed that using setjmp and longjmp to restart the division, you can get the behavior you want.
Note: on Unix there is another set of functions, sigaction, siglongjump and others, which is better to use. In fact I don't recommend using something else in any serious program.
I am trying to allow an interrupt to cause a certain value to be returned by readline. Here is a minimal example:
#include <stdio.h>
#include <signal.h>
#include <readline/readline.h>
void handler (int status)
{
rl_replace_line("word",0);
rl_redisplay();
rl_done = 1;
}
int main (int argc, char** argv)
{
char* entry;
signal(SIGINT,handler);
entry = readline("");
printf("\nEntry was: %s\n", entry);
return 0;
}
If I run this code and press Control-C, after I hit ENTER, sure enough it prints "Entry was: word". But I would like it to do so without the user needing to press ENTER. I basically just want to set entry to "word" when the interrupt signal is received, ending the readline function. I have been unable to find any documentation for how to just end the readline loop and return a certain value (I'm sure it's out there, but I haven't found it).
One thing I tried was adding
(*rl_named_function("accept-line"))(1,0);
at the end of handler, but it didn't send the text to "entry" immediately.
I think I have what you want running here.
#include <stdio.h>
#include <signal.h>
#include <readline/readline.h>
int event(void) { }
void handler (int status)
{
rl_replace_line("word",0);
rl_redisplay();
rl_done = 1;
}
int main (int argc, char** argv)
{
char* entry;
rl_event_hook=event;
signal(SIGINT,handler);
entry = readline("");
printf("\nEntry was: %s\n", entry);
return 0;
}
The secret is the rl_done is only checked in the event loop. When you give it a null event hook function, it checks the rl_done and exits.
I don't believe there is any guarantee that you can call back into readline functions from an asynchronous signal handler. (The fact that it "seems to" work does not guarantee that it will not fail disastrously from time to time.) In general, you should do the absolute minimum in a signal handler, such as setting a flag to indicate that the signal has been received.
The readline library provides the variable rl_signal_event_hook, whose value is a function which will be called when a readline call is interrupted by a signal. It would probably be wise to put any code which modifies the readline state into such a function.
But it seems like the safest solution here would be to arrange for the Control-C character to be passed directly to readline without triggering a SIGINT. You could create a custom terminal setting based on the termios struct returned by tcgetattr which turns off the mapping of Ctrl-C to the INTR function, either by unsetting the ISIG flag (which will also turn off other interrupt characters, including Ctrl-Z) or by changing c_cc[VINTR] to _POSIX_VDISABLE (or to some other key).
If you are on Windows and you are not using Cygwin, which includes termios emulation, you can use native APIs to enable and disable Control-C handling.
Then you can use rl_bind_key to bind Ctrl-C (which is 3) to your own function. The function needs to match the rl_command_func_t typedef, which is int(*)(int, int). The function should return 0; in your simple case, you can probably ignore the arguments, but for the record the first one is a "count" (the numeric argument, entered by typing a number while holding down the Alt key), and the second one is the key itself.
You should probably make a copy of the termios structure before you modify it so that you can reset the terminal settings once you're done. Generally, you would want to install and restore the terminal settings around every call to readline (which is what readline itself does, as well).
CTRL+C should pass a SIGINT, or similar interrupt signal to your program. There should be ways to override the handling, see here for example.
You can achieve this by using the alternate interface, where your code is doing the event loop and calls libreadline functions each time a character needs to be read from the terminal. In the event loop you can handle all extra asynchronous events like signals (but not only that --- think a terminal chat application where messages arrive asynchronously from the network).
Here's how it could look like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <readline/readline.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
static volatile sig_atomic_t my_signal_flag = 0;
static int done_loop = 0;
void my_signal_handler (int status)
{
my_signal_flag = 1; // set a volaatile sig-atomic_t var
// and exit, just as the standard says
}
void my_rlhandler(char* line) // all your app is in this function
// called each time a line is ready
{
if (line && strcmp(line, "quit"))
printf("Entry was: %s\n", line);
else
{
done_loop = 1;
rl_set_prompt("");
}
free(line);
}
void my_event_loop() // event loop
// handle all async events here
// signals, network, threads, whatever
{
rl_callback_handler_install("w00t>", my_rlhandler);
do
{
signal(SIGINT, my_signal_handler); // readline may override this
// better do it here each time
fd_set readfds; // prepare the select
FD_ZERO(&readfds);
FD_SET(0, &readfds);
if (select(1, &readfds, NULL, NULL, NULL) > 0)
{
rl_callback_read_char(); // character ready, let readline eat it
}
else if (my_signal_flag )
{
my_signal_flag = 0; // can get here only after a signal
rl_replace_line("word",0);
rl_done = 1;
rl_redisplay();
rl_pending_input = '\n'; // not sure why it's needed
rl_callback_read_char();
}
}
while (!done_loop);
rl_callback_handler_remove();
}
int main (int argc, char** argv)
{
char* entry;
signal(SIGINT, my_signal_handler);
my_event_loop();
return 0;
}
While this may seem more complicated that other methods, the callback interface is more appropriate for real-life programs that need to handle a variety of events.
I'm a student new to C Programming and am not fully understanding how signal catching works, and in line with character device drivers. I'd appreciate some help but I need to state that this is for a project that is due in my first C Programming class. So I have not posted any direct code, only an example of my initial approach.
My project needs to accept a signal input and set that signal to a variable to pass to my character device driver. Another program I've written will need to access that variable's value such that when read, it performs a certain outcome. I've tried to run my control program (<name> &) but it quits immediately. I double check by entering ps into my command prompt and the process is gone.
Basically I need my control program to pause and wait for the signal to be received. Once received, if the signal matches it will set a variable to its value. Otherwise, if it is SIGTERM it will either end or pause(), where it will wait until another signal is received that meets another condition. Currently, when I compile and run it with & it simply runs and quits. Here is an example of my code:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
void sig_handler(int sig);
void sig_handler(int sig){
while(1){
if(sig == SIGRTMIN){
printf("SIG = SIGRTMIN\n");
file_state = 0;
}else if(sig == SIGRTMIN+1){
printf("SIG = SIGRTMIN1\n");
file_state = 1;
}else if(sig == SIGTERM){
printf("Exiting\n");
exit(0); //exit
}else{
printf("SIG = %i\n", sig);
pause(); //doesn't match, pause for next signal
}
}
}
int main(){
signal(SIGINT, sig_handler);
//return 0; //tried with and without
}
I'm waiting until this daemon receives a signal to put the device driver into a particular mode. I haven't entered any write() methods yet because I'm trying to take this one step at a time where I send a signal with kill() and the proper response is returned with printf().
My problem is that I can't seem to keep this in pause() mode while I'm waiting for a signal that breaks the if loop. What's worse (other than my lack of knowledge and programming) is that I can't even keep this daemon open long enough to attempt a signal send. Once I can get this to pause and receive the signal, I plan to use the system write() method to write my file_state variable to the /dev/<filename>, which will be cross-referenced in my executable.
How far off am I? This is the final part that (I believe) I'm stuck on and I can't figure out how this should be approached. I've looked online and about 95% of the examples that delve into this contain methods we haven't learned yet. And if not, the examples are more simplistic where they do not include passing a value to a character device driver for use when another program is using the driver.
Any help is greatly appreciated.
ETA
I've updated my code so now it stays open until a signal is received. Problem is that I want this to pause() and remain open until the SIGTERM signal is received, breaking the loop and ending the program. I can't seem to get the loop correct. Even entering a conditional int variable into the while() loop still is broken when any signal is received. Here is my updated code below:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
int keep_alive = 1; //added for conditional checking to keep the while
//loop open to receive more than one signal
void sig_handler(int sig);
void sig_handler(int sig){
if(sig == SIGRTMIN){
printf("SIG = SIGRTMIN\n");
file_state = 0;
}else if(sig == SIGRTMIN+1){
printf("SIG = SIGRTMIN1\n");
file_state = 1;
}else if(sig == SIGTERM){
keep_alive = 0;
}else{
}
}
int main(){
do{
signal(SIGINT, sig_handler);
pause(); //thought pausing here would help with waiting for a new signal
}while(keep_alive == 1); //keep looping until false
return 0; //tried with and without
}
I'm trying to figure out a method to keep this process and signal catching loop alive until a specific signal is received. I can't figure it out for the life of me.
ETA 2
Discovered my issue. I wasn't paying attention and fully understanding the signal() method. The first argument requires the exact signal you are attempting to catch. I was using SIGINT which I was understanding it to be a "class" of interrupts that you wanted to catch. And then in the signal_handler() function, you would specify which type of interrupt you were catching. But, it is actually looking to catch the exact signal you are interested in. So in my example code, I should have been using:
int main(){
if(signal(SIGRMIN, sig_handler) == SIG_ERR){
printf("can't catch SIGRMIN Signal.\n")
}
...
}
I'm going to update with my new script as an answer and if anyone thinks it should be done differently or have any constructive criticisms please let me know. Thanks again!
So I found my issue, and it is working now. Below is my fixed code that produces the correct response back to the terminal when caught. I've added a for() loop to catch any other signals I'm not worried about didn't stop my process, only SIGTERM will. Look forward to getting critiqued and why I would never want to do my approach.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
void sig_handler(int sig);
void sig_handler(int sig){
if(sig == SIGRTMIN){
printf("SIG = SIGRTMIN\n");
file_state = 0;
}else if(sig == SIGRTMIN+1){
printf("SIG = SIGRTMIN1\n");
file_state = 1;
}else if(sig == SIGTERM){
exit(0);
EXIT_SUCCESS;
}else{
printf("SIGNAL CAUGHT #%d\n", sig);
}
}
int main(){
if(signal(SIGRTMIN, sig_handler)==SIG_ERR){
printf("Unable to catch SIGRTMIN\n");
}
if(signal(SIGRTMIN+1, sig_handler)==SIG_ERR){
printf("Unable to catch SIGRTMIN+1\n");
}
if(signal(SIGTERM, sig_handler)==SIG_ERR){
printf("Unable to terminate process.\n");
}
//This for loop will catch all other signals except the un-catchable and
//other user-specified above signal #31.
int s;
for(s = 0; s < 32; s++){
signal(s, sig_handler);
}
while(1);
pause();
return 0;
}
There are 2 parts, 1st user space where generation and catching of signals occurs. This has nothing to do with kernel driver. Your code seems okay about it.
2nd is interacting with driver when signal has been caught. For char driver have a look at this link. You can simply write a value write(fd, 1, &buf); from user space program and implement corresponding write() in char driver.
So I'm trying to call an alarm to display a message "still working.." every second.
I included signal.h.
Outside of my main I have my function: (I never declare/define s for int s)
void display_message(int s); //Function for alarm set up
void display_message(int s) {
printf("copyit: Still working...\n" );
alarm(1); //for every second
signal(SIGALRM, display_message);
}
Then, in my main
while(1)
{
signal(SIGALRM, display_message);
alarm(1); //Alarm signal every second.
That's in there as soon as the loop begins. But the program never outputs the 'still working...' message. What am I doing incorrectly? Thank you, ver much appreciated.
Signal handlers are not supposed to contain "business logic" or make library calls such as printf. See C11 ยง7.1.4/4 and its footnote:
Thus, a signal handler cannot, in general, call standard library functions.
All the signal handler should do is set a flag to be acted upon by non-interrupt code, and unblock a waiting system call. This program runs correctly and does not risk crashing, even if some I/O or other functionality were added:
#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
volatile sig_atomic_t print_flag = false;
void handle_alarm( int sig ) {
print_flag = true;
}
int main() {
signal( SIGALRM, handle_alarm ); // Install handler first,
alarm( 1 ); // before scheduling it to be called.
for (;;) {
sleep( 5 ); // Pretend to do something. Could also be read() or select().
if ( print_flag ) {
printf( "Hello\n" );
print_flag = false;
alarm( 1 ); // Reschedule.
}
}
}
Move the calls to signal and alarm to just before your loop. Calling alarm over and over at high speed keeps resetting the alarm to be in one second from that point, so you never reach the end of that second!
For example:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void display_message(int s) {
printf("copyit: Still working...\n" );
alarm(1); //for every second
signal(SIGALRM, display_message);
}
int main(void) {
signal(SIGALRM, display_message);
alarm(1);
int n = 0;
while (1) {
++n;
}
return 0;
}
Do not call alarm() twice, just call it once in main() to initiate the callback, then once in display_message().
Try this code on Linux (Debian 7.8) :
#include <stdio.h>
#include <signal.h>
void display_message(int s); //Function for alarm set up
void display_message(int s)
{
printf("copyit: Still working...\n" );
alarm(1); //for every second
signal(SIGALRM, display_message);
}
int main()
{
signal(SIGALRM, display_message);
alarm(1); // Initial timeout setting
while (1)
{
pause();
}
}
The result will be the following one :
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
copyit: Still working...
The alarm() call is for a one off signal.
To repeat an alarm, you have to call alarm() again each time the signal occurs.
Another issue, also, is that you're likely to get EINTR errors. Many system functions get interrupted when you receive a signal. This makes for much more complicated programming since many of the OS functions are affected.
In any event, the correct way to wait for the next SIGALRM is to use the pause() function. Something the others have not mentioned (instead they have tight loops, ugly!)
That being said, what you are trying to do would be much easier with a simple sleep() call as in:
// print a message every second (simplified version)
for(;;)
{
printf("My Message\n");
sleep(1);
}
and such a loop could appear in a separate thread. Then you don't need a Unix signal to implement the feat.
Note: The sleep() function is actually implemented using the same timer as the alarm() and it is clearly mentioned that you should not mix both functions in the same code.
sleep(3) may be implemented using SIGALRM; mixing calls to alarm() and sleep(3) is a bad idea.
(From Linux man alarm)
void alarm_handler(int)
{
alarm(1); // recurring alarm
}
int main(int argc, char *argv[])
{
signal(SIGALRM, alarm_handler);
alarm(1);
for(;;)
{
printf("My Message\n");
// ...do other work here if needed...
pause();
}
// not reached (use Ctrl-C to exit)
return 0;
}
You can create variations. For example, if you want the first message to happen after 1 second instead of immediately, move the pause() before the printf().
The "other work" comment supposes that your other work does not take more than 1 second.
It is possible to get the alarm signal on a specific thread if work is required in parallel, however, this can be complicated if any other timers are required (i.e. you can't easily share the alarm() timer with other functions.)
P.S. as mentioned by others, doing your printf() inside the signal handler is not a good idea at all.
There is another version where the alarm() is reset inside main() and the first message appears after one second and the loop runs for 60 seconds (1 minute):
void alarm_handler(int)
{
}
int main(int argc, char *argv[])
{
signal(SIGALRM, alarm_handler);
for(int seconds(0); seconds < 60; ++seconds)
{
alarm(1);
// ...do other work here if needed...
pause();
printf("My Message\n");
}
// reached after 1 minute
return 0;
}
Note that with this method, the time when the message will be printed is going to be skewed. The time to print your message is added to the clock before you restart the alarm... so it is always going to be a little over 1 second between each call. The other loop is better in that respect but it still is skewed. For a perfect (much better) timer, the poll() function is much better as you can specify when to wake up next. poll() can be used just and only with a timer. My Snap library uses that capability (look for the run() function, near the bottom of the file). In 2019. I moved that one .cpp file to the eventdispatcher library. The run() function is in the communicator.cpp file.
POSIX permits certain of its functions to be called from signal handling context, the async-signal safe functions, search for "async-sgnal safe" here. (These may be understood as "system calls" rather than library calls). Notably, this includes write(2).
So you could do
void
display_message (int s) {
static char const working_message [] = "copyit: Still working...\n";
write (1, working_message, sizeof working_message - sizeof "");
alarm(1); /* for every second */
}
By the way, precise periodic alarms are better implemented using setitimer(2),
since these will not be subject to drift. Retriggering the alarm via software, as done here, will unavoidably accumulate error over time because of the time spent executing the software as well as scheduling latencies.
In POSIX sigaction(2) superceedes signal(2) for good reason:
the original Unix signal handling model was simple. In particular,
a signal handler was reset to its original "deposition" (e.g., terminate
the process) once it was fired. You would have to re-associate
SIGALRM with display_message() by calling signal() just before
calling alarm() in display_message().
An even more important reason for using sigaction(2) is the
SA_RESTART flag. Normally, system calls are interrupted when
a signal handler is invoked. I.e., when then signal handler returns,
the system call returns an error indication (often -1) and errno is
set to EINTR, interrupted system call. (One reason for this
is to be able to use SIGALRM to effect time outs, another is
to have a higher instance, such as a user, to "unblock" the
current process by sending it a signal, e.g.,
SIGINT by pressing control-C at the terminal).
In your case, you want signal handling to be transparent
to the rest of the code, so you would set the SA_RESTART flag
when invoking sigaction(2). This means the kernel should
restart the interrupted system call automatically.
ooga is correct that you keep reloading the alarm so that it will never go off. This works. I just put a sleep in here so you don't keep stepping on yourself in the loop but you might want to substitute something more useful depending on where you are headed with this.
void display_message(int s)
{
printf("copyit: Still working...\n" );
// alarm(1); //for every second
// signal(SIGALRM, display_message);
}
int main(int argc, char *argv[])
{
int ret;
while(1)
{
signal(SIGALRM, display_message);
alarm(1);
if ((ret = sleep(3)) != 0)
{
printf("sleep was interrupted by SIGALRM\n");
}
}
return (0);
}
I need help to clear my concepts.
I have a function which toggle the Led status on/off after every second. Now the code for the on/off runs inside infite loop.
Example:
void ToggleLed( int pin_number)
{
// some code
while(1)
{
// code to execute the Led status
}
}
Now when I integrate this code with base line and called that function inside other function it just doesnt work no other functionality of software works.
Question: Function has infinite-loop and that it doesn't come out of control and other functions called after that function doesn't work.
If that is the case do I need to provide separate thread to it?
Any suggestion will be helpful.
Yes you will need a separate thread, or some other form of asynchronous execution. Once you enter that while loop, no other code runs in that thread. Ever.
If I understand correcctly nothing works in your integrated version. In that case, yes you probably need to run the infinite loop on a separate thread, because your function with the infinit loop will never exit, so no other code will ever run on that thread.
You don't say what OS, but yes, set it as a low-priority thread, minimal stack size. I flash a LED in my projects, just so I can easily see if the code has reached the abort-handler yet :)
void LEDflash_task_code(void *p)
{
while (1)
{
FIO1CLR=STATUS_LED;
OSsleep(750);
FIO1SET=STATUS_LED;
OSsleep(250);
};
};
If you have access to hardware peripheral timers (any micrcontroller/microprocessor application), you should use those hardware timers, not threads nor software sleep().
void init_toggle_led (uint32_t interval)
{
setup_hardware_timer(interval);
}
void toggle_led (void)
{
if( (hardware_timer_register & flag) > 0 )
{
port = port ^ pin_mask;
}
}
main()
{
init_toggle_led(1000);
for(;;)
{
do_stuff();
toggle_led();
}
}
This was an example with polling. Alternatively, you can use hardware interrupts from the timers and toggle the port from there.
As David mentioned, you should run your LED code in a separate thread. http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#BASICS
Once you have threads, if you want your code to be able to stop your LED from blinking, then add a flag that's checked inside the while loop at each iteration, and if it's set then break out.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void * toggle_led(void *ptr);
int stop=0;
int main (int argc, const char * argv[])
{
printf("Hello, World!\n");
// set up thread
pthread_t LED_thread;
char * message = "blink!";
pthread_create( &LED_thread, NULL, toggle_led, (void*) message);
// do some other work
sleep(5);
// ok you want to quit now
stop=1;
pthread_join(LED_thread, NULL);
printf("Goodbye!\n");
return 0;
}
void *toggle_led(void *ptr)
{
while (!stop)
{
printf("%s \n", (char *)ptr);
sleep(1);
}
}
I think you need to implement as a watchdog functionality. Because if you use threads then even if other threads has some issues(like deadlock), your LEDs will toggle as long as toggle_led thread works. You need to implement an toggle_led() function and call from each of other threads /functions before returning to make sure all other threads/functions are getting executed successfully without waiting continuously for some resources