How to break a sleeping thread in pthread?

I have a thread that has slept for a long time, then wakes up to do something, and then sleep again, for example:

while(some_condition) { // do something sleep(1000); } 

How can I make this thread elegant and FAST?

I tried using pthread_cancel() , but sleeping threads could not be undone. I also tried changing the condition of the while loop, but it still takes a lot of time to exit. And I do not want to use pthread_kill() , since it can kill a thread when it works.

So are there any good ideas?

+7
source share
3 answers

As an alternative to sleep you can use pthread_cond_timedwait with a timeout of 1000 ms. Then, when you want to exit, signal the condition variable.

This is similar to how you can do this in C # / Java using wait and notify.

+11
source

The classic UNIX state variable is a self-pipe .

 int fds[2]; pipe2(fds, O_NONBLOCK); // requires newish kernel and glibc; use pipe + 2*fcntl otherwise child: while (some_condition) { // do something struct pollfd pd = { .fd = fds[0], .events = POLLIN }; int rc; char c; while ((rc = poll(&pd, 1, 1000000)) == -1 && errno == EINTR) // not entirely correct; 1000000 should be decreased according to elapsed time when repeating after a signal interruption ; if (rc > 0 && (pd.revents & POLLIN) && read(fds[0], &c, 1) >= 0) break; } parent: cancel() { char c = 0; write(fds[1], &c, 1); } 

Yes, this is a very strange (and unverified) code. You should probably just use pthread_cond_wait , this requires pthread_mutex_t and pthread_cond_t , but it is much simpler.

0
source

Have you used pthread_cleanup_push and pop? Undo with pthread_cancel does not work without them. You should use them in pairs, as in the example below. if you forget the one that it will not compile (fancy macros, one has "{" and the other has "}"). You can even set different levels of cleaning / ascent. In any case, they set a point with a big jump, which cancels the transition when the cancellation occurs (pretty cool). In addition, if your test program does not wait for the start or stop of the stream, you may not notice the cancellation.

Example:

 #include <stdio.h> #include <stdlib.h> #include <pthread.h> static void *ThreadProc(void * arg); static void unwind(__attribute__ ((unused)) void *arg); int _fActive = 0; int main(int argc, char** argv) { pthread_t Thread; int nRet; nRet = pthread_create(&Thread, NULL, ThreadProc, NULL); printf("MAIN: waiting for thread to startup...\n"); while (_fActive == 0) nanosleep(&(struct timespec){ 0, 0}, NULL); printf("MAIN: sending cancel...\n"); nRet = pthread_cancel(Thread); printf("MAIN: waiting for thread to exit...\n"); while (_fActive) nanosleep(&(struct timespec){ 0, 0}, NULL); printf("MAIN: done\n"); return 0; } static void unwind(__attribute__ ((unused)) void *arg) { // do some cleanup if u want printf("THREAD: unwind (all threads, canceled or normal exit get here)\n"); _fActive = 0; } static void *ThreadProc(void * arg) { pthread_cleanup_push(unwind, arg); // optional : pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); printf("THREAD: Enter Sleep\n"); _fActive = 1; sleep(1000000); printf("THREAD: Exit Sleep (canceled thread never gets here)\n"); pthread_cleanup_pop(1); printf("THREAD: Exit (canceled thread never gets here)\n"); return NULL; } 

Program output:

 MAIN: waiting for thread to startup... THREAD: Enter Sleep MAIN: sending cancel... MAIN: waiting for thread to exit... THREAD: unwind (all threads, canceled or normal exit get here) MAIN: done 

Note how canceling cancels ThreadProc at the cancel point of sleep () and only performs the unwind () function.

0
source

All Articles