c++ - Cancelling thread that is stuck on epoll_wait -
i'm doing event handling c++ , pthreads. have main thread reads event queue defined, , worker thread fills event queue. queue of course thread safe.
the worker thread have list of file descriptors , create epoll system call events on file descriptors. uses epoll_wait wait events on fd's.
now problem. assuming want terminate application cleanly, how can cancel worker thread properly? epoll_wait
not 1 of cancellation points of pthread(7) cannot react on pthread_cancel
.
the worker thread main() looks this
while(m_workerrunning) { epoll_wait(m_epolldescriptor, events, maxevents, -1); //handle events , insert queue }
the m_workerrunning
set true
when thread starts , looks can interrupt thread settings m_workerrunning
false main thread. problem epoll_wait
theoretically can wait forever.
other solution though is: instead of waiting forever (-1) can wait example x time slots, handle no-events case , if m_workerrunning == false
exit loop , terminate worker thread cleanly. main thread sets m_workerrunning
false, , sleeps x. i'm not sure performance of such epoll_wait , not sure correct x? 500ms? 1s? 10s?
i'd hear experienced advises!
more relevant information: fd's i'm waiting events on, devices in /dev/input
technically i'm doing sort of input subsystem. targeted os linux (latest kernel) on arm architecture.
thanks!
you send thread signal interupt blocking call epoll_wait()
. if doing modify code this:
while(m_workerrunning) { int result = epoll_wait(m_epolldescriptor, events, maxevents, -1); if (-1 == result) { if (eintr == errno) { /* handle shutdown request here. */ break; } else { /* error handling goes here. */ } } /* handle events , insert queue. */ }
a way add signal handler:
#include <signal.h> /* generic signal handler doing nothing */ void signal_handler(int sig) { sig = sig; /* cheat compiler not give warning unused variable. */ } /* wrapper set signal handler */ int signal_handler_set(int sig, void (*sa_handler)(int)) { struct sigaction sa = {0}; sa.sa_handler = sa_handler; return sigaction(sig, &sa, null); }
to set handler signal sigusr1
do:
if (-1 == signal_handler_set(sigusr1, signal_handler)) { perror("signal_handler_set() failed"); }
to send signal sigusr1
process:
if (-1 == kill(<target process' pid>, sigusr1)) { perror("kill() failed"); }
to have process send signal itself:
if (-1 == raise(sigusr1)) { perror("raise() failed"); }
Comments
Post a Comment