Skip site navigation (1)Skip section navigation (2)
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>