如何使用sem_trywait()?

时间:2014-12-04 13:12:21

标签: c multithreading semaphore

如何测试信号量是否被阻止?

我尝试sem_trywait()功能,但它没有w,我现在不知道为什么,你能帮我吗?

示例在此处(使用信号量解决睡眠理发问题的示例程序。):http://users.dickinson.edu/~braught/courses/cs354s00/classes/code/SleepBarber.src.html

我希望使用sem_trywait()来检测信号量阻塞:

 void *customer(void *number) {
    int num = *(int *)number;

    //there is my problem...
    //you must waiting to free semaphore...
    while(sem_trywait(&waitingRoom)){
        printf("Semaphore is full you must wait!");
    }

    // Wait for space to open up in the waiting room...
    sem_wait(&waitingRoom);
    printf("Customer %d entering waiting room.\n", num);

    // Wait for the barber chair to become free.
    sem_wait(&barberChair);

    // The chair is free so give up your spot in the
    // waiting room.
    sem_post(&waitingRoom);

    // Wake up the barber...
    printf("Customer %d waking the barber.\n", num);
    sem_post(&barberPillow);

    // Wait for the barber to finish cutting your hair.
    sem_wait(&seatBelt);

    // Give up the chair.
    sem_post(&barberChair);
    printf("Customer %d leaving barber shop.\n", num);
}

问题出在while循环

while(sem_trywait(&waitingRoom)){
    printf("Semaphore is full you must wait!");
}

我不知道如何使用它。谢谢。


EDIT1:

void *customer(void *number) {
    int num = *(int *) number;

    // Leave for the shop and take some random amount of
    // time to arrive.

    printf("Customer %d arrived at barber shop.\n", num);

    if (sem_trywait(&waitingRoom) == 0) {
        // Wait for space to open up in the waiting room...
        sem_wait(&waitingRoom);
        printf("Customer %d entering waiting room--------------------------------------------.\n", num);

        // Wait for the barber chair to become free.
        sem_wait(&barberChair);

        // The chair is free so give up your spot in the
        // waiting room.
        sem_post(&waitingRoom);

        // Wake up the barber...
        printf("Customer %d waking the barber.\n", num);
        sem_post(&barberPillow);

        // Wait for the barber to finish cutting your hair.
        sem_wait(&seatBelt);

        // Give up the chair.
        sem_post(&barberChair);
        printf("Customer %d leaving barber shop.\n", num);
    } else {
        printf("leaving barber shop %d\n", num);
        customer(&num);
        //sem_wait(X);
    }


}

2 个答案:

答案 0 :(得分:3)

首先是一般性警告,我会降低您的确切问题。不要使用sem_trywait,除非您有非常具体的理由这样做并且非常了解信号量和锁定。这适用于所有锁定函数,互斥锁,rwlock等。如果存在锁定函数的“try”版本,那么它适用于非特定情况,不适用于99%的用户。

sem_wait将以最有效的方式等待信号量。你在sem_trywait周围循环时旋转将几乎(但不完全)与sem_wait完全相同,只是你会非常低效地浪费CPU时间并可能阻止其他人释放信号量。< / p>

sem_trywait和其他“try”锁定函数适用于您无法等待锁定的情况,而您宁愿失败操作而不是等到锁定可用。很少有应用程序实际上有这样的要求。这可能发生在硬实时系统或某些非常复杂的锁定方案中,其中失败是避免锁定排序问题的唯一方法。

大多数应用程序没有此问题。例如,您的示例代码根本没有此问题。第一个sem_wait将满足您的需求。如果您只想在获取信号量时记录消息,您想要做的是这样的事情:

if (sem_trywait(X) == 0) {
    printf("semaphore acquired\n");
} else {
    printf("need to wait for semaphore\n");
    sem_wait(X);
}

您的代码的问题在于您首先尝试等待,然后再次成功,您再次等待,这是不正确的,因为如果trywait成功,则意味着它与sem_wait执行相同的操作。

答案 1 :(得分:0)

不要使用while循环进行测试。尝试只等一次并检查结果。

result = sem_trywait(...);
if (result == -1) { 
    // Check one of: EAGAIN, EDEADLK, EINTR, EINVAL
}

然后决定循环,如果你需要等待更多。