Date: Thu, 06 Aug 1998 18:11:01 -0400 From: "Daniel M. Eischen" <eischen@vigrid.com> To: eischen@vigrid.com, shmit@kublai.com Cc: freebsd-current@FreeBSD.ORG Subject: Re: Pthreads woes revisited. Message-ID: <35CA29F5.41C67EA6@vigrid.com>
next in thread | raw e-mail | index | archive | help
I (Daniel Eischen) wrote:
>
> (from main)
> 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);
>
> Sleeping while holding the mutex will obviously not allow the
> other thread to run. When the main thread returns from the sleep,
> it will run until its time quantum expires, preempted, or blocks
> (perhaps signals can affect it too?). I ran the same test on
> Solaris and the main thread *never* yielded the processor to the
> other thread until I placed a pthread_yield (sched_yield) after
> the pthread_cond_signal.
>
> Please try adding some sort of blocking operation after the
> pthread_cond_signal in the main thread. If you do not want to
> use pthread_yield(), then use sleep, select, or anything that
> will block the main thread.
>
> I suspect that you want the thread to run while the main thread
> is sleeping. If that is the case, then you must use another mutex
> in the main thread.
Instead of using sleep, use pthread_cond_timedwait with a timeout
of 1 sec. This will release the busy mutex and let the other thread
run:
int
main(int argc, char *argv[])
{
int rc;
pthread_t thread_id;
pthread_cond_t sleep_cv;
struct timespec ts;
rc = pthread_cond_init(&wakeup, NULL);
if (rc == 0)
rc = pthread_cond_init(&sleep_cv, NULL);
if (rc) {
fprintf(stderr,
"ERROR: couldn't create condition variables: %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;
}
clock_gettime (CLOCK_REALTIME, &ts);
ts.tv_sec++;
rc = pthread_cond_timedwait (&sleep_cv, &busy, &ts);
if (rc != 0 && rc != ETIMEDOUT) {
fprintf(stderr, "ERROR: pthread_cond_wait failed: %s.\n",
strerror(rc));
return 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;
}
}
return 0;
}
Dan Eischen
eischen@vigrid.com
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?35CA29F5.41C67EA6>
