cancelling a thread inside a signal handler - c++

I have started a timer and set the interval as 5 secs and registered a signal handler for it.
When SIGALRM is encountered iam trying to terminate the thread inside the signal handler, bt not able to do that. Thread is not getting terminated , instead of this whole process is killed.
The following is the code:
void signalHandler()
{
printf("Caught signal ...\n");
printf("Now going to terminate thread..\n");
pthread_kill(tid, SIGKILL);
}
void * thread_function()
{
int oldstate;
char result[256] = {0};
time_t startTime = time(NULL);
time_t timerDuration = 5;
time_t endTime = startTime + timerDuration;
while(1) {
printf("Timer is runnuing as dameon..\n");
if(!strcmp(result, "CONNECTED")) {
resp = 1;
pthread_exit(&resp);
}
}
}
int main()
{
int *ptr[2];
signal(SIGALRM, signalHandler);
timer.it_interval.tv_usec = 0;
timer.it_interval. tv_usec = 0;
timer.it_value.tv_sec = INTERVAL;
timer.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &timer, 0);
pthread_create(&tid, NULL, thread_function, NULL);
pthread_join(tid, (void**)&(ptr[0]));
printf("test %d\n\n",*ptr[0]);
while(1)
printf("1");
}
Platform : Linux , gcc compiler

As far as I'm aware you pretty much can't call anything inside a signal handler as you don't know what state your code is in.
Your best option is to set up a thread to handle your signals. All your other threads should call pthread_setsigmask and to block all signals, and then you create another thread, which calls calls pthread_setsigmask to catch SIGALARM, and then calls sigwait, at which point it can cancel the other thread.

The way of handling signals is much different in a multi-threaded environment as compared to a single threaded environment. In a multi-threaded code, you should block out all the signals for all the threads that have your business logic and then create a seperate thread for handling the signals. This is because, in multi-threaded environment, you cannot be sure to which thread the signal will be delivered.
Please refer to this link for more details:
http://devcry.heiho.net/2009/05/pthreads-and-unix-signals.html
Apart from this, to kill a thread use pthread_cancel which should work fine for you.

You can try using a flag:
int go_on[number_of_threads] = { 1 };
void signalHandler()
{
printf("Caught signal ...\n");
printf("Now going to terminate thread..\n");
go_on[tid] = 0;
}
void * thread_function()
{ /* */
while(go_on[this_thread_id]) {
printf("Timer is runnuing as dameon..\n");
if(!strcmp(result, "CONNECTED")) {
resp = 1;
pthread_exit(&resp);
}
}
}

Related

Setting timeout for c/c++ function call

Suppose my main function calls an external function veryslow()
int main(){... veryslow();..}
Now I would like to the invocation part of very_slow in main, so that veryslow terminates if it runs out of a time bound. Something like this
int main(){... call_with_timeout(veryslow, 0.1);...}
What is a simple way to achieve that? My OS is Ubuntu 16.04.
You can call this function in a new thread, and set a timeout to terminate the thread, it will end this function call.
A POSIX example would be:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
pthread_t tid;
// Your very slow function, it will finish running after 5 seconds, and print Exit message.
// But if we terminate the thread in 3 seconds, Exit message will not print.
void * veryslow(void *arg)
{
fprintf(stdout, "Enter veryslow...\n");
sleep(5);
fprintf(stdout, "Exit veryslow...\n");
return nullptr;
}
void alarm_handler(int a)
{
fprintf(stdout, "Enter alarm_handler...\n");
pthread_cancel(tid); // terminate thread
}
int main()
{
pthread_create(&tid, nullptr, veryslow, nullptr);
signal(SIGALRM, alarm_handler);
alarm(3); // Run alarm_handler after 3 seconds, and terminate thread in it
pthread_join(tid, nullptr); // Wait for thread finish
return 0;
}
You can use future with timeout.
std::future<int> future = std::async(std::launch::async, [](){
veryslow();
});
std::future_status status;
status = future.wait_for(std::chrono::milliseconds(100));
if (status == std::future_status::timeout) {
// verySlow() is not complete.
} else if (status == std::future_status::ready) {
// verySlow() is complete.
// Get result from future (if there's a need)
auto ret = future.get();
}
Note that there's no built-in way to cancel an async task. You will have to implement that inside verySlow itself.
See here for more:
http://en.cppreference.com/w/cpp/thread/future/wait_for
i would pass a pointer to an interface into the function and ask for one back. with this i would enable two way communication to perform all necessary tasks--including timeout and timeout notification.

create threads but don't run it immediately in linux

I am trying to execute my program in threads, I use pthread_create(), but it runs the threads immediately. I would like to allow the user to change thread priorities before running. How it is possible to resolve?
for(int i = 0; i < threads; i++)
{
pthread_create(data->threads+i,NULL,SelectionSort,data);
sleep(1);
print(data->array);
}
Set the priority as you create the thread.
Replace
errno = pthread_create(..., NULL, ...);
if (errno) { ... }
with
pthread_attr_t attr;
errno = pthread_attr_init(&attr);
if (errno) { ... }
{
struct sched_param sp;
errno = pthread_attr_getschedparam(&attr, &sp);
if (errno) { ... }
sp.sched_priority = ...;
errno = pthread_attr_setschedparam(&attr, &sp);
if (errno) { ... }
}
/* So our scheduling priority gets used. */
errno = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (errno) { ... }
errno = pthread_create(..., &attr, ...);
if (errno) { ... }
errno = pthread_attr_destroy(&attr);
if (errno) { ... }
For pthreads the priority isn't set after thread creation but rather by passing suitable attributes upon thread creation: the thread attributes go where you have specified NULL in your pthread_create() call. If you want to delay thread creation until the user has given you a priority you can create a function object expecting the priority and upon call of that function object you'd kick off the thread. Of course, you'll still need to keep track of the thus created object (possibly using a std::future<...>-like object) to later join that thread.
Note that providing an answer shouldn't be construed as endorsing thread priorities: as far as I can tell, playing with thread priorities are ill-advised.

Qt timers cannot be stopped from another thread

Hy,
I'm writing my first Qt program and getting now in troubles with:
QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread
My program will communicate to a CANOpen bus for that I'm using the Canfestival Stack. The Canfestival will work with callback methods. To detects timeout in communication I setup a timer function (somehow like a watchdog). My timer package consist out of a "tmr" module, a "TimerForFWUpgrade" module and a "SingleTimer" module. The "tmr" module was originally C programmed so the static "TimerForFWUpgrade" methods will interface it. The "tmr" module will be part of a C programed Firmware update package.
The timer will work as follows. Before a message is sent I will call TMR_Set method. An then in my idle program loop with TMR_IsElapsed we check for a timer underflow. If TMR_IsElapsed I will do the errorhandling. As you see the TMR_Set method will be called continuously and restart the QTimer again and again.
The above noted errors are appearing if I start my program. Can you tell me if my concept could work? Why does this errors appear? Do I have to use additional threads (QThread) to the main thread?
Thank you
Matt
Run and Idle loop:
void run
{
// start communicate with callbacks where TMR_Set is set continously
...
while(TMR_IsElapsed(TMR_NBR_CFU) != 1);
// if TMR_IsElapsed check for errorhandling
....
}
Module tmr (interface to C program):
extern "C"
{
void TMR_Set(UINT8 tmrnbr, UINT32 time)
{
TimerForFWUpgrade::set(tmrnbr, time);
}
INT8 TMR_IsElapsed(UINT8 tmrnbr)
{
return TimerForFWUpgrade::isElapsed(tmrnbr);
}
}
Module TimerForFWUpgrade:
SingleTimer* TimerForFWUpgrade::singleTimer[NR_OF_TIMERS];
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent)
{
for(unsigned char i = 0; i < NR_OF_TIMERS; i++)
{
singleTimer[i] = new SingleTimer(parent);
}
}
//static
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
time *= TimerForFWUpgrade::timeBase;
singleTimer[tmrnbr]->set(time);
}
}
//static
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
if(true == singleTimer[tmrnbr]->isElapsed())
{
return 1;
}
else
{
return 0;
}
}
Module SingleTimer:
SingleTimer::SingleTimer(QObject* parent) : QObject(parent),
pTime(new QTimer(this)),
myElapsed(true)
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_setElapsed()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->setSingleShot(true);
}
void SingleTimer::set(unsigned int time)
{
myElapsed = false;
pTime->start(time);
}
bool SingleTimer::isElapsed()
{
QCoreApplication::processEvents();
return myElapsed;
}
void SingleTimer::slot_setElapsed()
{
myElapsed = true;
}
Use QTimer for this purpose and make use of SIGNALS and SLOT for the purpose of starting and stopping the timer/s from different threads. You can emit the signal from any thread and catch it in the thread which created the timer to act on it.
Since you say you are new to Qt, I suggest you go through some tutorials before proceeding so that you will know what Qt has to offer and don't end up trying to reinvent the wheel. :)
VoidRealms is a good starting point.
You have this problem because the timers in the static array is created in Thread X, but started and stopped in Thread Y. This is not allowed, because Qt rely on thread affinity to timeout timers.
You can either create, start stop in the same thread or use signal and slots to trigger start and stop operations for timers. The signal and slot solution is a bit problematic Because you have n QTimer objects (Hint: how do you start the timer at position i?)
What you can do instead is create and initialize the timer at position tmrnbr in
TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
singleTimer[tmrnbr] = new SingleTimer(0);
singleTimer[tmrnbr]->set(time);
}
which is executed by the same thread.
Futhermore, you don't need a SingleTimer class. You are using Qt5, and you already have all you need at your disposal:
SingleTimer::isElapsed is really QTimer::remainingTime() == 0;
SingleTimer::set is really QTimer::setSingleShot(true); QTimer::start(time);
SingleTimer::slot_setElapsed becomes useless
ThusSingleTimer::SingleTimer becomes useless and you dont need a SingleTimer class anymore
I got the errors away after changing my timer concept. I'dont use anymore my SingleTimer module. Before the QTimer I won't let timeout and maybe because of that I run into problems. Now I have a cyclic QTimer that times out every 100ms in slot function I will then count the events. Below my working code:
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent) : QObject(parent),
pTime(new QTimer(this))
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_handleTimer()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->start(100);
}
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
if(timeBase != 0)
{
myTimeout[tmrnbr] = time / timeBase;
}
else
{
myTimeout[tmrnbr] = 0;
}
myTimer[tmrnbr] = 0;
myElapsed[tmrnbr] = false;
myActive[tmrnbr] = true;
}
}
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
QCoreApplication::processEvents();
if(tmrnbr < NR_OF_TIMERS)
{
if(true == myElapsed[tmrnbr])
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0; // NOK
}
}
void TimerForFWUpgrade::slot_handleTimer()
{
for(UINT8 i = 0; i < NR_OF_TIMERS; i++)
{
if(myActive[i] == true)
{
myTimer[i]++;
if(myTimeout[i] < myTimer[i])
{
myTimer[i] = 0;
myElapsed[i] = true;
myActive[i] = false;
}
}
}
}

using libev with multiple threads

I want to use libev with multiple threads for the handling of tcp connections. What I want to is:
The main thread listen on incoming connections, accept the
connections and forward the connection to a workerthread.
I have a pool of workerthreads. The number of threads depends on the
number of cpu's. Each worker-thread has an event loop. The worker-thread listen if I can write on the tcp socket or if
somethings available for reading.
I looked into the documentation of libev and I known this can be done with libev, but I can't find any example how I have to do that.
Does someone has an example?
I think that I have to use the ev_loop_new() api, for the worker-threads and for the main thread I have to use the ev_default_loop() ?
Regards
The following code can be extended to multiple threads
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2009 debuguo
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
#include <ev.h>
#include <stdio.h> // for puts
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
double timeout = 0.00001;
ev_timer timeout_watcher;
int timeout_count = 0;
ev_async async_watcher;
int async_count = 0;
struct ev_loop* loop2;
void* loop2thread(void* args)
{
printf("Inside loop 2"); // Here one could initiate another timeout watcher
ev_loop(loop2, 0); // similar to the main loop - call it say timeout_cb1
return NULL;
}
static void async_cb (EV_P_ ev_async *w, int revents)
{
//puts ("async ready");
pthread_mutex_lock(&lock); //Don't forget locking
++async_count;
printf("async = %d, timeout = %d \n", async_count, timeout_count);
pthread_mutex_unlock(&lock); //Don't forget unlocking
}
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
//puts ("timeout");
if (ev_async_pending(&async_watcher)==false) { //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
}
pthread_mutex_lock(&lock); //Don't forget locking
++timeout_count;
pthread_mutex_unlock(&lock); //Don't forget unlocking
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
if (argc < 2) {
puts("Timeout value missing.\n./demo <timeout>");
return -1;
}
timeout = atof(argv[1]);
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
//Initialize pthread
pthread_mutex_init(&lock, NULL);
pthread_t thread;
// This loop sits in the pthread
loop2 = ev_loop_new(0);
//This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.)
//This takes into account thread safety
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop2, &async_watcher);
pthread_create(&thread, NULL, loop2thread, NULL);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive
ev_loop(loop, 0);
//Wait on threads for execution
pthread_join(thread, NULL);
pthread_mutex_destroy(&lock);
return 0;
}
Using libev within different threads at the same time is fine as long as each of them runs its own loop[1].
The c++ wrapper in libev (ev++.h) always uses the default loop instead of letting you specify which one you want to use. You should use the C header instead (ev.h) which allows you to specify which loop to use (e.g. ev_io_start takes a pointer to an ev_loop but the ev::io::start doesn't).
You can signal another thread's ev_loop safely through ev_async.
[1]http://doc.dvgu.ru/devel/ev.html#threads_and_coroutines

force exit from readline() function

I am writing program in c++ which runs GNU readline in separate thread. When main thread is exited I need to finish the thread in which readline() function is called. The readline() function is returned only when standart input came (enter pressed).
Is there any way to send input to application or explicitly return from readline function?
Thanks in advance.
Instead of returning from main thread, call exit(errno). All other threads will be killed nastily!
Or, if you wanted to be nicer, and depending on your OS, you could send a signal to the readline thread, which would interrupt the syscall.
Or, if you wanted to be cleverer, you could run readline in async mode, using a select() loop with a timeout so that your thread never blocks in readine functions, and your thread can clean up after itself.
I experimented with this situation as well. I thought perhaps one could call close(STDIN_FILENO), which does cause readline to return on the other thread, but for some reason it leaves the terminal in a bad state (doesn't echo characters so you can't see what you're typing). However, a call to the 'reset' command will fix this, so the full alternative is:
close(STDIN_FILENO);
pthread_join(...); // or whatever to wait for thread exit
system("reset -Q"); // -Q to avoid displaying cruft
However, the final better solution I used, inspired by the other suggestions, was to override rl_getc:
rl_getc_function = getc; // stdio's getc passes
and then you can use pthread_kill() to send a signal to interrupt the getc, which returns a -1 to readline, which returns a NULL to the calling thread so you can exit cleanly instead of looping for the next input (the same as would happen if the user EOF'd by ctrl-D)
Now you can have your cake (easy blocking readlines) and eat it too (be able to stop by external event without screwing up the terminal)
C++ standard input is not designed to be thread safe. So, even if there was a method to programatically stop it from waiting input, you wouldn't be able to call it from another thread. Of course, there could be an implementation specific way to do so.
Old thread but still readline API seems not explored.
In order to interrupt readline first I disabled readline signal handlers.
Do not look at the ugly global_buffer I'm using - it's just an example
http://www.delorie.com/gnu/docs/readline/rlman_43.html
Reader Thread:
pthread_mutex_t lock;
int isBufferReady = 0;
char global_buffer[2500]; /// Assuming that reads will not be any bigger
void *reader_thread(void *arg)
{
rl_getc_function = getc;
rl_catch_signals = 0;
rl_catch_sigwinch = 0;
char *input;
while ( (input = readline( NULL )) )
{
i = strlen(input)-1;
if ( input[i] == '\0' )
return NULL;
/// Due to TAB there might be a whitespace in the end
while ( i > 0 )
{
if ( isspace(input[i]) )
{
input[i] = '\0';
}
else
{
break;
}
i--;
}
pthread_mutex_lock(&lock);
read_file_function( input, buffer );
free(input);
isBufferReady = 1;
pthread_mutex_unlock(&lock);
}
printf( "Im closed \n" );
return NULL;
}
Signal handler:
volatile int keepRunning = 1;
void SIG_handler(int signal)
{
int static sig_count = 0;
switch ( signal )
{
case SIGUSR2:
{
/// Yeah I know I should not printf in a signal handler
printf( "USR2: %d \n", sig_count++);
break;
}
default:
{
printf( " SIGHANDLE\n" );
keepRunning = 0;
break;
}
}
}
main:
int main( int argc, char *argv[] )
{
pthread_t file_reader;
{ /// Signal Handler registration
struct sigaction sigact = {{0}};
sigact.sa_handler = SIG_handler;
// sigact.sa_flags = SA_RESTART;
sigaction(SIGINT , &sigact, NULL);
sigaction(SIGQUIT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGHUP, &sigact, NULL);
// sigaction(SIGUSR1, &sigact, NULL);
sigaction(SIGUSR2, &sigact, NULL);
}
pthread_create( &file_reader, NULL, reader_thread, NULL );
while(keepRunning)
{
pthread_mutex_lock(&lock);
if( !isBufferReady )
{
... fill in global_buffer according to some algorithm
}
pthread_mutex_unlock(&lock);
usleep(10);
pthread_mutex_lock(&lock);
if(isBufferReady)
isBufferReady = 0;
... some operation on the 'global_buffer' like write its contents to socket
pthread_mutex_unlock(&lock);
usleep(10);
}
signal(SIGINT, SIG_DFL);
pthread_cancel( file_reader );
pthread_join( file_reader, NULL);
pthread_mutex_destroy(&lock);
rl_cleanup_after_signal();
return 0;
}
With this (nowhere near perfect) code snippet I was able to finally interrupt readline without described prevously flakiness.
Used this code snippet for interactive debug purposes where I had prepared packets in simple text files and read-in those files with the help of readline.