Date: Fri, 19 Nov 1999 08:28:56 -0800 From: "Scott Hess" <scott@avantgo.com> To: <freebsd-hackers@freebsd.org> Subject: EINTR problems with multithreaded programs. Message-ID: <030f01bf32ab$2d2c5620$1e80000a@avantgo.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. ------=_NextPart_000_030C_01BF3268.1EFCBA10 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit 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 ------=_NextPart_000_030C_01BF3268.1EFCBA10 Content-Type: application/octet-stream; name="thread_EINTR.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="thread_EINTR.c" #include <pthread.h>=0A= #include <errno.h>=0A= #include <sys/types.h>=0A= #include <signal.h>=0A= =0A= static void *reader( void *arg)=0A= {=0A= char buf[ 1024];=0A= int cc;=0A= int fd=3D(int)arg;=0A= =0A= while(1) {=0A= printf( "%p waiting for data\n", pthread_self());=0A= cc=3Dread( fd, buf, sizeof( buf));=0A= if( cc>=3D0) {=0A= printf( "%p got %d bytes\n", pthread_self(), cc);=0A= } else {=0A= printf( "%p saw errno=3D=3D%d/%s\n", pthread_self(), errno, = strerror( errno));=0A= }=0A= }=0A= return NULL;=0A= }=0A= =0A= static void signal_handler( int sig)=0A= {=0A= printf( "Got signal %d\n", sig);=0A= }=0A= =0A= void main( void)=0A= {=0A= int ii, cc=3D10;=0A= pthread_t child;=0A= =0A= #if 0=0A= signal( SIGUSR1, signal_handler);=0A= #else=0A= {=0A= struct sigaction sa=3D{ signal_handler, 0, SA_RESTART};=0A= sigaction( SIGUSR1, &sa, NULL);=0A= }=0A= #endif=0A= =0A= for( ii=3D0; ii<cc; ii++) {=0A= if( pthread_create( &child, NULL, reader, (void *)dup( 0))) {=0A= perror( "spawning thread");=0A= exit( 1);=0A= }=0A= }=0A= while( 1) {=0A= sleep( 2);=0A= kill( getpid(), SIGUSR1);=0A= }=0A= exit( 0);=0A= }=0A= ------=_NextPart_000_030C_01BF3268.1EFCBA10-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?030f01bf32ab$2d2c5620$1e80000a>