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>
