I have a very strange problem in C. A function from a proprietary library reduces sleep(n) to sleep(0).
My code looks like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /*sleep() */
int main(int argc, char** argv){
//...
AStreamEngine.init();
AStreamEngine.setCodec(3);
AStreamEngine.start(); //problematic function
printf("a");
sleep(100);
printf("b");
return 0;
}
If the problematic function is commented out, then printing "a" follows by printing "b" after 100 sec. But if isn't commented out, "ab" is printed. So the program ends very quickly and I cannot notice if the engine works.
I found that:
if I replace sleep() by getchar() the engine works correctly.
if I put active waiting by a for-loop then it also works.
Does anyone have any idea why happens? And how to fix (bypass) this feature/bug? I don't want use getchar and active waiting.
Update:
I don't have source of the library. I have only binary .so file.
Base on responces I add a below code add end:
struct timespec to_sleep = { 1, 0 };
int ret = nanosleep(&to_sleep,&to_sleep);
printf("%d\n",ret);
if(ret == -1){
printf(" break sleep : %d %s", errno,strerror(errno));
}
And I get output:
-1
break sleep : 4 Interrupted system callc
Now I try to bypass by thread.
"sleep" can be interrupted by signals - see http://man7.org/linux/man-pages/man3/sleep.3.html . My guess is that the "start" function started a thread which might have caused signals to be sent to your program. Put "sleep" in a loop like this:
unsigned int x = 100;
while (x > 0) { x = sleep (x); }
Another point: printf may be line-buffered. In that mode, the output is only seen if you print a "\n" character. Try using "a\n".
As rightly said by Jack, usleep and sleep can be interrupted by the delivery of signals (E.g presence of ioctl, read, write function calls).
One of the smart way to avoid this issue is to use nanosleep. Like sleep and usleep, nanosleep can also be interrupted by the delivery of signals but the difference is, its second argument tells you how much time is remaining.
You can use this argument to make sure your code sleeps for the specified amount of time. Replace your sleep and usleep function with a while loop containing nanosleep. Following is the example usage,
struct timespec to_sleep = { 1, 0 }; // Sleep for 1 second
while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
Off course this solutions is not suitable for the application where exact amount sleep is required but it is very useful in the cases where minimum delay is required before executing next function.
After examination, I think that the using of the sleep() function is useless on your case.
Indeed, the sleep function uses the pause() function, which wait for a signal and stops if your process receive a signal call.
In your case it's probably the problem, and it explains why the sleep() function stops when you call the AStreamEngine.start() function.
I think that the best solution is to use the usleep() function, which should not stops if your process receive a signal.
Try this :
usleep(VALUE_IN_MILISECONDS);
Good luck ! :)
Related
I'm porting a software from an embedded computer to a Linux machine. (Ubuntu 14.04 or Raspbian (raspberry pi))
The original program was using setjmp/longjmp to handle timeout and CTRL+C event. It was running on a Microcontroller with a single main (one thread).
I'm trying to have a similar behaviour while using threads (pthreads).
The idea is that I want either a timeout or a CTRL+C to restart an infinite loop.
The original code was doing something like the code below. I don't mind to drop the setjmp/longjmp by something else. (ex: try/catch or signal or pthread_kill, conditional variable, etc..)
Any idea how to implement similar behavior with C/C++ ?
Here is the code which seems to partially work and is probably not recommended/broken:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <setjmp.h>
// Define
#define TICK_NS_TIME (10000000) // 0.01 sec = 10 ms (100 times per second)
#define NS_PER_SEC (1000000000) // Nano sec per second.
#define TICK_PER_SEC (NS_PER_SEC/TICK_NS_TIME) // Number of tick per second (Ex:100)
#define TIMEOUT_COUNT (30*TICK_PER_SEC) // 30 seconds timeout (with 100 tick per second)
// Env set/long jmp
#define ENV_SZ (2)
#define ENV_TIMEOUT (0)
#define ENV_CTRLC (1)
static jmp_buf env[ENV_SZ];
// Variables
int timeout_val;
// sig handler.
void signal_handler(int signo)
{
pthread_t self = pthread_self();
printf("Thread %lu in signal handler\n", (long)self);
if (signo == SIGINT) {
longjmp(env[ENV_CTRLC], 1); // Q?: Is it in the same thread ? (Never, Always, Sometimes?)
}
else
{
printf("Other signal received..quitting."); // Ex: kill -9 pid
exit(0);
}
}
// thread timer function
void* timer_function(void* in_param)
{
// Loop approx 100x per second.
for (;;) {
nanosleep((const struct timespec[]){{0, TICK_NS_TIME }}, NULL); // Sleep 10 ms seconds.
if (timeout_val) {
if (!--timeout_val) {
longjmp(env[ENV_TIMEOUT], 1); // longjmp when timer reaches 0. (Q?: Is this valid with multithread?)
}
}
}
}
// main
int main(int argc, char **argv)
{
int i;
int val;
struct sigaction actions;
pthread_t thread;
setvbuf (stdout, NULL, _IONBF, 0); // Make sure stdout is not buffered (ex:printf, etc.)
printf("[Program started]\r\n");
memset(&actions, 0, sizeof(actions));
sigemptyset(&actions.sa_mask);
actions.sa_flags = 0;
actions.sa_handler = signal_handler;
val = sigaction(SIGINT, &actions, NULL);
pthread_create(&thread, NULL, timer_function, NULL); // timer thread for example
printf("[Timer thread started]\r\n");
// setting env.
val = setjmp(env[ENV_TIMEOUT]);
if (val!=0){ printf("[JMP TIMEOUT]\r\n"); }
val = setjmp(env[ENV_CTRLC]);
if (val!=0){ printf("[JMP CTRLC]\r\n"); }
// main loop
timeout_val = TIMEOUT_COUNT;
i = 0;
for (;;)
{
i++;
if (i > 10){ i = 0; printf("[%d]", timeout_val/TICK_PER_SEC); } // Number of seconds before time out.
sleep(1);
printf(".");
}
printf("Main completed\n");
return 0;
}
//Compile: g++ -pthread main.cpp -o main
Suggestion for alternative implementation would be great since I'm new to programming with threads !
setjmp() saves the information required to restore the calling environment. longjmp() can then restore this environment, but only within the same thread.
The C11 standard is explicit about the constraint of having the same thread:
7.13.2.1/2 If there has been no such invocation (i.e: of a previous setjmp), or if the invocation was from another thread of
execution, or if the function containing the invocation of the
setjmp macro has terminated execution in the interim, or if the
invocation of the setjmp macro was within the scope of an identifier
with variably modified type and execution has left that scope in the
interim, the behavior is undefined.
In fact, setjmp/longjmp are generally implemented by saving the stack pointer so that restoring it makes sense only int the same execution context.
Alternative
Unless I've missed something, you use the second thread only to act as a timer. You could instead get rid of your POSIX pthread, and use a timer signal activated with POSIX timer_create().
But be aware that using setjmp/longjmp from a signal handler (so already in your original code for CTRL+C) is tricky, as explained in this SO answer. So you'd consider sigsetjmp/siglongjmp.
For the records: C or C++ ?
Your question is tagged C. But you mention c++ try and catch. So for the sake of completeness:
in C++ setjmp should be replaced by a try/catch and the longjmp by throwing an exception. setjmp/longjmp are supported in C++ only if unwinding the stack wouldn't require invocation of any non-trivial destructor (see C++ standard, 18.10/4).
the exceptions are not propagated across the threads, unless catched and explicitely rethrown using std::rethrow_exception(). It's delicate, so refer to this SO question for for additional details. But it's possible and could solve your issue.
I used the command "clear" in C language at infinite loop just for test and the kill signal does not stop it.
Why the program does not stop when i press Ctrl + C ?
#include <stdlib.h>
int main () {
while (1) {
system("clear");
}
return 0;
}
Killing clear will not help, because the infinite loop is in your own program. Kill that.
ControlC is only useful if you can get the system to pay attention. It sounds as if your terminal is too busy writing to the screen to do this.
From another terminal, run top and kill your program (which likely is near the top of the screen).
You could include a signal handler to 'catch' your CRTL-C input (which is SIGINT below) and then exit. Hopefully, this stub code will give you the idea. If not, I can provide a complete working example but would like to see you try first. :-)
#include <signal.h>
...
void stop (int signal) {
exit;
}
int main() {
signal(SIGINT, stop);
...
}
HTH
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);
}
This program
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
void INThandler(int);
int main(void)
{
signal(SIGINT, INThandler);
char data[128];
int n;
while((n=read(0, data, 128)) > 0)
{
if(data[n] = '\n') break;
}
data[n] ='\0';
printf("%s", data);
return 0;
}
void INThandler(int sig)
{
char c;
signal(sig, SIG_IGN);
printf("OUCH, did you hit Ctrl-C?\n"
"Do you really want to quit? [y/n] ");
c = getchar();
if (c == 'y' || c == 'Y')
exit(0);
else
signal(SIGINT, INThandler);
}
Doesn't handle ctrl-c, but terminates at that input.
If I replace everything between the handler install and the return by
while (1)
Sleep(1);
the handler function is called and works but I want to have the read() in there.
EDIT: Looking back at this program, I noticed that I have
if(data[n] = '\n') break;
I wrote '=' instead of '==', but by using the later, it doesn't work properly and I don't understand why. Shouldn't it be a comparison to detect '\n'?
Also, I messed around with the buffer, but I can't make keep the input if I hit CTRL-C.
The example code does not take into accounts two issues:
read() will abort it's work if its process receives a signal (see man 2 read)
It is only guaranteed for a few functions that they can be called savely from a signal handler function (see man 7 signal). printf()and getch() do not not belong to this set of "save" functions.
The first issue could be fixed using a more differentiated way to handle the value returned by read(). I should counts how much data had already been read, together with some smart adjustment of the buffer passed to read().
Regarding the second issue, read() and write() are the functions of choice to perform input/output to/from a signal handler as those are listed to be "save" functions by the man-page mentioned above.
It's because of the implementation of read(2) you use doesn't allow that. Here is what I get when I compile your program, execute it and press ^C:
$ ./program
^COUCH, did you hit Ctrl-C?
Do you really want to quit? [y/n] y
$
or if I answer n and enter some data:
$ ./program
^COUCH, did you hit Ctrl-C?
Do you really want to quit? [y/n] n
test
test
$
Since read(2) is a system call, it depends on the system you use. I use Linux (3.2.0-4-686-pae) and here it's behaving correctly. Maybe you should consider to use scanf(3) or fread(3) with stdio(3) instead, for the platform you're using (which I take to be win32)? Or also use a different implementation, like the ones from Cygwin or MinGW?
I am working on a program with a fixed number of threads in C using posix threads.
How can i be notified when a thread has been terminated due to some error?
Is there a signal to detect it?
If so, can the signal handler create a new thread to keep the number of threads the same?
Make the threads detached
Get them to handle errors gracefully. i.e. Close mutexs, files etc...
Then you will have no probolems.
Perhaps fire a USR1 signal to the main thread to tell it that things have gone pear shaped (i was going to say tits up!)
Create your threads by passing the function pointers to an intermediate function. Start that intermediate function asynchronously and have it synchronously call the passed function. When the function returns or throws an exception, you can handle the results in any way you like.
With the latest inputs you've provided, I suggest you do something like this to get the number of threads a particular process has started-
#include<stdio.h>
#define THRESHOLD 50
int main ()
{
unsigned count = 0;
FILE *a;
a = popen ("ps H `ps -A | grep a.out | awk '{print $1}'` | wc -l", "r");
if (a == NULL)
printf ("Error in executing command\n");
fscanf(a, "%d", &count );
if (count < THRESHOLD)
{
printf("Number of threads = %d\n", count-1);
// count - 1 in order to eliminate header.
// count - 2 if you don't want to include the main thread
/* Take action. May be start a new thread etc */
}
return 0;
}
Notes:
ps H displays all threads.
$1 prints first column where PID is displayed on my system Ubuntu. The column number might change depending on the system
Replace a.out it with your process name
The backticks will evaluate the expression within them and give you the PID of your process. We are taking advantage of the fact that all POSIX threads will have same PID.
I doubt Linux would signal you when a thread dies or exits for any reason. You can do so manually though.
First, let's consider 2 ways for the thread to end:
It terminates itself
It dies
In the first method, the thread itself can tell someone (say the thread manager) that it is being terminated. The thread manager will then spawn another thread.
In the second method, a watchdog thread can keep track of whether the threads are alive or not. This is done more or less like this:
Thread:
while (do stuff)
this_thread->is_alive = true
work
Watchdog:
for all threads t
t->timeout = 0
while (true)
for all threads t
if t->is_alive
t->timeout = 0
t->is_alive = false
else
++t->timeout
if t->timeout > THRESHOLD
Thread has died! Tell the thread manager to respawn it
If for any reason one could not go for Ed Heal's "just work properly"-approach (which is my favorite answer to the OP's question, btw), the lazy fox might take a look at the pthread_cleanup_push() and pthread_cleanup_pop() macros, and think about including the whole thread function's body in between such two macros.
The clean way to know whether a thread is done is to call pthread_join() against that thread.
// int pthread_join(pthread_t thread, void **retval);
int retval = 0;
int r = pthread_join(that_thread_id, &retval);
... here you know that_thread_id returned ...
The problem with pthread_join() is, if the thread never returns (continues to run as expected) then you are blocked. That's therefore not very useful in your case.
However, you may actually check whether you can join (tryjoin) as follow:
//int pthread_tryjoin_np(pthread_t thread, void **retval);
int retval = 0;
int r = pthread_tryjoin_np(that_thread_id, &relval);
// here 'r' tells you whether the thread returned (joined) or not.
if(r == 0)
{
// that_thread_id is done, create new thread here
...
}
else if(errno != EBUSY)
{
// react to "weird" errors... (maybe a perror() at least?)
}
// else -- thread is still running
There is also a timed join which will wait for the amount of time you specified, like a few seconds. Depending on the number of threads to check and if your main process just sits around otherwise, it could be a solution. Block on thread 1 for 5 seconds, then thread 2 for 5 seconds, etc. which would be 5,000 seconds per loop for 1,000 threads (about 85 minutes to go around all threads with the time it takes to manage things...)
There is a sample code in the man page which shows how to use the pthread_timedjoin_np() function. All you would have to do is put a for loop around to check each one of your thread.
struct timespec ts;
int s;
...
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
/* Handle error */
}
ts.tv_sec += 5;
s = pthread_timedjoin_np(thread, NULL, &ts);
if (s != 0) {
/* Handle error */
}
If your main process has other things to do, I would suggest you do not use the timed version and just go through all the threads as fast as you can.