#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
using namespace std;
int count = 0;
void alarm2(int signo)
{
cout << count;
}
void alarm1(int signo)
{
signal(SIGALRM, alarm2);
cout << "ctrl+C";
alarm(10);
sleep(10);
}
int main()
{
signal(SIGALRM, alarm1);
alarm(3);
sleep(5);
}
I want that after 3 seconds I get the message "ctrl+C" and then another alarm set for 10 seconds; after that I should get the value of count. But when I run after just 10 sec I get "ctrl+C" and the value of count.
In your example you made many, many mistakes.
First of all look at documentation about which function is safe to call from
signal handlers:
https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers
Of course functions that can allocate memory is not safe to call, because of it is not safe to call malloc.
Because of it is not right to call printf or std::ostream::opeartor<< (std::cout <<) in signal handler.
Second, in documentation (type man 3 sleep) clearly written it is not safe mix sleep and alarm,
Third you not wait enough in main function, so it can exit before the second alarm handler run.
Here is how it can be done:
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
volatile sig_atomic_t done = 0;
void alarm2(int signo)
{
write(STDOUT_FILENO, "alarm2\n", sizeof("alarm2\n") - 1);
done = 1;
}
void alarm1(int signo)
{
signal(SIGALRM, alarm2);
write(STDOUT_FILENO, "ctrl+C\n", sizeof("ctrl+C\n") - 1);
alarm(10);
}
int main()
{
signal(SIGALRM, alarm1);
alarm(3);
while (done == 0)
sleep(1); //sleep can be wake up by alarm signal, so check flag
}
Add "<< endl;" to all your cout statements and try again.
Related
Let's say I have a foo() function. I want it to run in, for example, 5 seconds, after that, it has to be cancelled and continues to do the rest of the program.
Code snippets:
int main() {
// Blah blah
foo(); // Running in 5 sec only
// After 5 sec, came here and finished
}
References: After a while searching on StackOverflow, I found this is what I need but written in python: Timeout on a function call.
signal.h and unistd.h can be related.
This is possible with threads. Since C++20, it will be fairly simple:
{
std::jthread t([](std::stop_token stoken) {
while(!stoken.stop_requested()) {
// do things that are not infinite, or are interruptible
}
});
using namespace std::chrono_literals;
std::this_thread::sleep_for(5s);
}
Note that many interactions with the operating system cause the process to be "blocked". An example of such is the POSIX function listen, which waits for incoming connections. If the thread is blocked, then it will not be able to proceed to the next iteration.
Unfortunately, the C++ standard doesn't specify whether such platform specific calls should be interrupted by request to stop or not. You need to use platform specific methods to make sure that happens. Typically, signals can be configured to interrupt blocking system calls. In case of listen, an option is to connect to the waiting socket.
There is no way to do that uniformly in C++. There are ways to do this with some degree of success when you use OS specific APIs, however it all becomes extremely cumbersome.
The basic idea which you can use in *nix is a combination of alarm() system call and setjmp/longjmp C function.
A (pseudo) code:
std::jmp_buf jump_buffer;
void alarm_handle(int ) {
longjmp(jump_buffer);
}
int main() {
signal(SIGALRM, alarm_handle);
alarm(5);
if (setjmp(jump_buffer)) {
foo(); // Running in 5 sec only
} else {
// After 5 sec, came here and finished
// if we are here, foo timed out
}
}
This all is extremely fragile and shaky (i.e. long jumps do not place nicely with C++ objects lifetime), but if you know what you are doing this might work.
Perfectly standard C++11
#include <iostream>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
using namespace std;
// stop flag
bool stopfoo;
// function to run until stopped
void foo()
{
while( ! stopfoo )
{
// replace with something useful
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << "still working!\n";
}
std::cout "stopped\n";
}
// function to call a top after 5 seconds
void timer()
{
std::this_thread::sleep_for (std::chrono::seconds( 5 ));
stopfoo = true;
}
int main()
{
// initialize stop flag
stopfoo = false;
// start timer in its own thread
std::thread t (timer);
// start worker in main thread
foo();
return 0;
}
Here is the same thing with a thread safe stop flag ( not really neccessary, but good practice for more complex cases )
#include <iostream>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
#include <mutex>
using namespace std;
class cFlagThreadSafe
{
public:
void set()
{
lock_guard<mutex> l(myMtx);
myFlag = true;
}
void unset()
{
lock_guard<mutex> l(myMtx);
myFlag = false;
}
bool get()
{
lock_guard<mutex> l(myMtx);
return myFlag;
}
private:
bool myFlag;
mutex myMtx;
};
// stop flag
cFlagThreadSafe stopfoo;
// function to run until stopped
void foo()
{
while( ! stopfoo.get() )
{
// replace with something useful
this_thread::sleep_for (std::chrono::seconds(1));
cout << "still working!\n";
}
cout << "stopped\n";
}
// function to call a top after 5 seconds
void timer()
{
this_thread::sleep_for (chrono::seconds( 5 ));
stopfoo.set();
}
int main()
{
// initialize stop flag
stopfoo.unset();
// start timer in its own thread
thread t (timer);
// start worker in main thread
foo();
t.join();
return 0;
}
And if it is OK to do everything in the main thread, things can be greatly simplified.
#include <iostream>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
using namespace std;
void foo()
{
auto t1 = chrono::steady_clock ::now();
while( chrono::duration_cast<chrono::seconds>(
chrono::steady_clock ::now() - t1 ).count() < 5 )
{
// replace with something useful
this_thread::sleep_for (std::chrono::seconds(1));
cout << "still working!\n";
}
cout << "stopped\n";
}
int main()
{
// start worker in main thread
foo();
return 0;
}
I would like to measure the execution time of some code. The code starts in the main() function and finishes in an event handler.
I have a C++11 code that looks like this:
#include <iostream>
#include <time.h>
...
volatile clock_t t;
void EventHandler()
{
// when this function called is the end of the part that I want to measure
t = clock() - t;
std::cout << "time in seconds: " << ((float)t)/CLOCKS_PER_SEC;
}
int main()
{
MyClass* instance = new MyClass(EventHandler); // this function starts a new std::thread
instance->start(...); // this function only passes some data to the thread working data, later the thread will call EventHandler()
t = clock();
return 0;
}
So it is guaranteed that the EventHandler() will be called only once, and only after an instance->start() call.
It is working, this code give me some output, but it is a horrible code, it uses global variable and different threads access global variable. However I can't change the used API (the constructor, the way the thread calls to EventHandler).
I would like to ask if a better solution exists.
Thank you.
Global variable is unavoidable, as long as MyClass expects a plain function and there's no way to pass some context pointer along with the function...
You could write the code in a slightly more tidy way, though:
#include <future>
#include <thread>
#include <chrono>
#include <iostream>
struct MyClass
{
typedef void (CallbackFunc)();
constexpr explicit MyClass(CallbackFunc* handler)
: m_handler(handler)
{
}
void Start()
{
std::thread(&MyClass::ThreadFunc, this).detach();
}
private:
void ThreadFunc()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
m_handler();
}
CallbackFunc* m_handler;
};
std::promise<std::chrono::time_point<std::chrono::high_resolution_clock>> gEndTime;
void EventHandler()
{
gEndTime.set_value(std::chrono::high_resolution_clock::now());
}
int main()
{
MyClass task(EventHandler);
auto trigger = gEndTime.get_future();
auto startTime = std::chrono::high_resolution_clock::now();
task.Start();
trigger.wait();
std::chrono::duration<double> diff = trigger.get() - startTime;
std::cout << "Duration = " << diff.count() << " secs." << std::endl;
return 0;
}
clock() call will not filter out executions of different processes and threads run by scheduler in parallel with program event handler thread. There are alternative like times() and getrusage() which tells cpu time of process. Though it is not clearly mentioned about thread behaviour for these calls but if it is Linux, threads are treated as processes but it has to be investigated.
clock() is the wrong tool here, because it does not count the time actually required by the CPU to run your operation, for example, if the thread is not running at all, the time is still counted.
Instead you have to use platform-specific APIs, such as pthread_getcpuclockid for POSIX-compliant systems (Check if _POSIX_THREAD_CPUTIME is defined), that counts the actual time spent by a specific thread.
You can take a look at a benchmarking library I wrote for C++ that supports thread-aware measuring (see struct thread_clock implementation).
Or, you can use the code snippet from the man page:
/* Link with "-lrt" */
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
thread_start(void *arg)
{
printf("Subthread starting infinite loop\n");
for (;;)
continue;
}
static void
pclock(char *msg, clockid_t cid)
{
struct timespec ts;
printf("%s", msg);
if (clock_gettime(cid, &ts) == -1)
handle_error("clock_gettime");
printf("%4ld.%03ld\n", ts.tv_sec, ts.tv_nsec / 1000000);
}
int
main(int argc, char *argv[])
{
pthread_t thread;
clockid_t cid;
int j, s;
s = pthread_create(&thread, NULL, thread_start, NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
printf("Main thread sleeping\n");
sleep(1);
printf("Main thread consuming some CPU time...\n");
for (j = 0; j < 2000000; j++)
getppid();
pclock("Process total CPU time: ", CLOCK_PROCESS_CPUTIME_ID);
s = pthread_getcpuclockid(pthread_self(), &cid);
if (s != 0)
handle_error_en(s, "pthread_getcpuclockid");
pclock("Main thread CPU time: ", cid);
/* The preceding 4 lines of code could have been replaced by:
pclock("Main thread CPU time: ", CLOCK_THREAD_CPUTIME_ID); */
s = pthread_getcpuclockid(thread, &cid);
if (s != 0)
handle_error_en(s, "pthread_getcpuclockid");
pclock("Subthread CPU time: 1 ", cid);
exit(EXIT_SUCCESS); /* Terminates both threads */
}
How can I determine this for the following program?
if (fork()){
if(!fork()){
if(fork()){
fork();
}
}
}
exit(0);
Five. The original process, plus one for each fork call. Add a sleep statement and print call to validate.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("Process Starting\n");
if (fork()){
if(!fork()) {
if(fork()){
fork();
}
}
}
printf("Process Exiting\n");
sleep(2); // sleep 2 seconds
return 0;
}
I'm asserting you'll see 5 "Process Exiting" statements printed.
I would like to use the following C++ code to wait for a predefined amount of time (in this example always 2 seconds), but still be interruptible by a signal (that's why I don't use sleep):
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <iostream>
using namespace std;
int measure() {
itimerval idle;
sigset_t sigset;
int sig;
idle.it_value.tv_sec = 2;
idle.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &idle, NULL); // TODO: check return value
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM); // TODO return values
sigaddset(&sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &sigset, NULL); // TODO return value?
sigwait(&sigset, &sig); // TODO check return value
while(sig != SIGUSR1) {
cout << "Hohoho" << endl;
idle.it_value.tv_sec = 2;
idle.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &idle, NULL); // TODO: check return value
sigwait(&sigset, &sig); // TODO check return value
}
cout << "Done with measurements." << endl;
return 0;
}
int main(int argc, char **argv) {
//if(fork() != 0) exit(0);
//if(fork() == 0) exit(0);
return measure();
}
I would expect this code to print "Hohoho" every 2 seconds until it receives SIGUSR1. Then it prints "Done with measurements." and exits. The second part works as expected. However, I see no "Hohoho", so it seems to me that the SIGALRM from setitimer somehow is not received. The strange thing is that if I do a fork before, the program works as expected. More specifically, if I uncomment either one of the two fork commands at the end, it works. Hence it does not depend on if it's the parent or child process, but somehow the fork event matters. Can someone explain to me what's going on and how to fix my code?
Thanks a lot,
Lutz
(1) Your setitimer is failing because you haven't set it correctly. Struct itimerval contains two structs of type timeval. You are only setting one and thereby picking up whatever garbage was in local storage when idle was declared.
struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
If you want a repeating timer every 2 seconds then set the 2nd set to repeat with the same values.
idle.it_value.tv_sec = 2;
idle.it_value.tv_usec = 0;
idle.it_interval.tv_sec = 2;
idle.it_interval.tv_usec = 0;
I am currently trying to implement a server in C++ using sockets. I am trying to prevent race conditions by blocking the SIGINT signal until it is stuck in the blocking pselect. From there, it should be exiting, changing my loop variable, and then quitting the thread. From my attempts at getting this working, it appears that it reaches the pselect(), but it does not get interrupted using my code. Any help is appreciated.
Listener.h:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
class CListener
{
public:
CListener();
void quitListener(void);
private:
void* InitListener(void);
static void* StartListenerThread(void* context);
static bool mbListening;
pthread_t mtThreadID;
};
Listener.cpp
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include "Listener.h"
bool CListener::mbListening = true;
CListener::CListener()
{
mbListening = true;
mtThreadID = 0;
pthread_create(&mtThreadID, NULL, &CListener::StartListenerThread, this);
}
void* CListener::StartListenerThread(void* context)
{
return ((CListener*)context)->InitListener();
}
void* CListener::InitListener()
{
sigset_t tSignalSet;
sigset_t tOriginalSignalSet;
sigemptyset(&tSignalSet);
sigaddset(&tSignalSet, SIGINT);
sigprocmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);
FD_ZERO(&tConnectionSet);
FD_SET(0, &tConnectionSet);
while(mbListening)
{
tSelectSet = tConnectionSet;
std::cout << "Reached pselect\n";
nReadyConnections = pselect(nSelectSocket+1, &tSelectSet,
NULL, NULL, NULL, &tOriginalSignalSet);
std::cout << "Broke out of pselect\n";
if(nReadyConnections < 0 && errno == EINTR)
{
mbListening = false;
}
}
pthread_exit(NULL);
return NULL;
}
void CListener::quitListener()
{
raise(SIGINT);
}
As long as I copied everything correctly fingers crossed you should just be able to run:
CListener tListener = CListener();
usleep(20000);
tListener.quitListener();
and the outputs should be displayed in terminal. My end goal is that I can allow for pselect to be interrupted without breaking any processing that may come after and allowing the thread to close gracefully. (blocking at pselect > recieve SIGINT > interupt pselect > return to loop > finish up and exit)
I've solved my own problem. Since I am generating a thread, I needed to add functions that allow for that, as well as adding a signal handler, like shown below.
void CListener::quitListener()
{
pthread_kill(mtThreadID,SIGINT);
}
void CListener::installSIGINTHandler()
{
signal(SIGINT, CListener::SIGINTHandler);
}
void CListener::SIGINTHandler(int signo)
{
mbListening = false;
}
And needed to change the sig mask setup to this:
pthread_sigmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);