Date: Thu, 06 Aug 1998 13:51:57 -0400 From: "Daniel M. Eischen" <eischen@vigrid.com> To: shmit@kublai.com Cc: freebsd-current@FreeBSD.ORG Subject: Re: Pthreads woes revisited. Message-ID: <35C9ED3D.41C67EA6@vigrid.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------446B9B3D2781E494167EB0E7 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit > I've put together a small C program that demonstrates the problems > I described in my last message. You can find the program attached > to this message. > > Note the location of the `sleep(1)' call, it's important. If it moves > outside of the mutex lock/unlock bits, everything functions normally, > but if it gets called after the lock, but before the unlock, the first > signal is missed. > But your not yielding the CPU after the pthread_cond_signal(). The waiter thread (thr_wait) should also take the mutex lock (busy) before the pthread_cond_wait(). See the comments in the revised copy of your code. Dan Eischen eischen@vigrid.com --------------446B9B3D2781E494167EB0E7 Content-Type: text/plain; charset=us-ascii; name="thr_test.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="thr_test.c" #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <string.h> pthread_cond_t wakeup; pthread_mutex_t busy; void * thr_routine(void *arg) { int rc; /* * The mutex should be taken before the condition wait. * The condition wait will atomically release the mutex and * retake it when awoken. */ pthread_mutex_lock (&busy); for (;;) { printf("%d: Waiting for signal.\n", (int) pthread_self ()); rc = pthread_cond_wait(&wakeup, &busy); if (rc) { fprintf(stderr, "ERROR: couldn't wait for condition: %s.\n", strerror(rc)); return NULL; } printf("%d: Got signal.\n", (int) pthread_self ()); } return NULL; } int main(int argc, char *argv[]) { int rc; pthread_t thread_id; rc = pthread_cond_init(&wakeup, NULL); if (rc) { fprintf(stderr, "ERROR: couldn't create condition variable: %s.\n", strerror(rc)); return 1; } rc = pthread_mutex_init(&busy, NULL); if (rc) { fprintf(stderr, "ERROR: couldn't create mutex: %s.\n", strerror(rc)); return 1; } rc = pthread_create(&thread_id, NULL, thr_routine, NULL); if (rc) { fprintf(stderr, "ERROR: couldn't create thread: %s.\n", strerror(rc)); return 1; } for (;;) { printf("MASTER: Acquiring lock.\n"); rc = pthread_mutex_lock(&busy); if (rc) { fprintf(stderr, "ERROR: couldn't lock mutex: %s.\n", strerror(rc)); return 1; } sleep(1); printf("MASTER: Releasing lock.\n"); rc = pthread_mutex_unlock(&busy); if (rc) { fprintf(stderr, "ERROR: couldn't unlock mutex: %s.\n", strerror(rc)); return 1; } printf("MASTER: Sending signal.\n"); rc = pthread_cond_signal(&wakeup); if (rc) { fprintf(stderr, "ERROR: couldn't signal thread: %s.\n", strerror(rc)); return 1; } /* Allow the other thread to run. */ pthread_yield (); } return 0; } --------------446B9B3D2781E494167EB0E7-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35C9ED3D.41C67EA6>