3

I'm writing a program that uses the POSIX thread library. I'm performing some return value of system calls, such as:

if (pthread_join(temp, NULL) != 0) {  
    cerr << "system error\n" << endl;  
    exit(1);  
}  

I want the program to exit immediately when it passes this if condition, but there could be a problem when the cpu decides to switch to a different thread right before the 'exit(1)' command.
Is there a way to protect such cases?

using a special mutex for this wouldn't help because: 1. i have many calls like this and locking each would make the code very slow, inefficient, and mostly - very ugly! 2. Each mutex requires its own return value check! So that obviously doesn't solve the initial problem..
Any helping ideas?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Zach
  • 537
  • 4
  • 9
  • 19
  • 2
    Formatted your code for you. In the future, please take the time to do this yourself. It only took me about 3 seconds. – John Dibling Apr 07 '11 at 15:37
  • Could you explain the race condition? I don't see any problem with what's shown here. Even if the kernel does switch away, it will come back and the program will (eventually) exit. Is this some horribly volatile or time-sensitive thing? – Chris Eberle Apr 07 '11 at 15:37
  • @Jenna Please explain why you need to prevent potential context switches. – NPE Apr 07 '11 at 15:38
  • @JohnDibling: In the future, please take a little more than 3 seconds, and do it properly. – Lightness Races in Orbit Apr 07 '11 at 15:38
  • @Chris: the problem is that if i get a failure on the join or unlock for example, and than keep running for a while - i sometimes get a seg fault or a deadlock, since the program is not suitable for running - which is why i exit in the first place... – Zach Apr 07 '11 at 15:41
  • @Jenna: You might be better off striving to avoid problems that destabilize your program in the first place, rather than focusing your attention on how to cleanly terminate after the fact. – NPE Apr 07 '11 at 15:45
  • If your program becomes SO unstable that even switching back to the other thread may segfault, you've got bigger issues. I mean I can sympathize, but you need to address the instability rather than how cleanly this exits. If this is non-production code, just live with the crash. If this IS production code, exiting in a clean manner only hides the problem. – Chris Eberle Apr 07 '11 at 15:45

2 Answers2

1

Use GCC atomic to write to a commonly used variable. Every thread should check this variable periodically. If this variable is changed, exit from the thread. The main thread do exit, when all other threads were finished.

One more link.

Naszta
  • 7,560
  • 2
  • 33
  • 49
  • the problem is that the scheduler may bring me to anywhere in the code of a different thread..so i can't just check this variable before each code line.. – Zach Apr 07 '11 at 15:45
  • @Jenna: in this case: use to change the common value by the atomic and use `pthread_exit` for all exit point. The strategy is the same: if the marker variable is not null, all other thread should exit in the same way. If all thread do exit, the application is do exit, too. – Naszta Apr 07 '11 at 15:50
  • You need not even use an atomic, using a plain normal global works the same. Atomicity is only important with concurrency, and there is none in this case. Checking the global every once in a while (for example, in a worker thread, each time before pulling a task from the queue) will normally be perfectly fine. If that is not good enough, you can still install a signal handler per thread and use `pthread_kill` to send a signal to each thread (preferrably not SIGTERM, because that will terminate the whole process). – Damon Apr 07 '11 at 16:01
0

Looks like there IS an answer for this, but I don't know how effective it is (i.e. if the program is already having issues, this may or may not work).

Can I prevent a Linux user space pthread yielding in critical code?

Community
  • 1
  • 1
Chris Eberle
  • 47,994
  • 12
  • 82
  • 119