When using -pthread on FreeBSD3.3 to build a multithreaded program, I find
that signals are delivered to all threads (see attached program).
Specifically, if multiple threads are in blocking read calls, and a signal
is handled, they will all receive -1 from the read and EINTR in errno.

We're running MYSQL with a large number of connections (>1000), many of
which are idle at any given time (in a blocking read), and MYSQL uses alarm
signals in many places (it appears to be on a per-handled-query basis, but
I've not been able to pin this down quite yet).  The net result is that
with many idle connections and many active connections, the idle
connections get a _lot_ of EINTR.  By default, MYSQL takes 10 EINTR in a
row before dropping the connection - I've modified that upwards, but then
substantial amounts of CPU time are spent catching the EINTR and throwing
the thread back into the read (it's a relatively cheap operation - but
might happen a couple hundred thousand times a second).

I've tried using sigaction() in hopes of letting the system know that it
can restart the interrupted read(), but that doesn't seem to do the trick
in the attached program.  Any other options?

[Right now I'm seriously considering adding small sleeps to the EINTR case
in MYSQL.  At least then all the threads won't wake up on every signal.  I
know, I know, I should fix the use of signals, too, but that's going to
take a couple more weeks of becoming one with the code.]

Thanks,
scott

thread_EINTR.c

Reply via email to