是否有内置的信号量结构可以等待多个资源?

时间:2019-04-24 20:26:03

标签: c semaphore

我希望能够一次等待/发布多个资源。是否有内置的c结构和接口可以做到这一点?

当前我正在使用semaphore.h,但是此接口的局限性在于它一次只能请求一个资源。

我可以做这样的事情:

for (int i = 0; i < resources; i++)
    sem_wait(my_sem);

但是,如果resources很大,那将很耗时,并且在此之前我还需要添加另一个锁,这样可以保证请求者的优先级高于可能正在请求资源的其他线程。 最终看起来像这样:

sem_wait(my_lock);
for (int i = 0; i < resources; i++)
    sem_wait(my_sem);
sem_post(my_lock);

更不用说需要进行额外的错误检查了。

我想做的是这样的:

sem_wait(my_lock, resources);

这将简单地等待所有资源可用,然后在将信号量减少所需数量的资源之后返回。我觉得我已经看过类似的东西了,但是似乎无法弄清楚。

1 个答案:

答案 0 :(得分:1)

您当前正在使用POSIX信号量。除了创建新的信号量之外,它们不能直接提供原子量改变一个以上信号量的可能性。

系统V信号量(semget / semctl / semop)通常被认为是劣等的,但是它们确实具有POSIX风格所缺乏的某些功能,这就是其中之一。具体来说,您可以使用semop()从信号量的值中原子扣除所有正数,直到将其阻塞而不将其值减小到零以下为止。

但是总体而言,System V IPC足以让人痛苦,我建议设置一个代表当前可用资源数量的共享变量,并使用互斥体+条件变量而不是信号量。看起来像这样:

unsigned resources_available = ALL_RESOURCES;
pthread_mutex_t resource_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t resource_cv = PTHREAD_COND_INITIALIZER;

// ...

int acquire_resources(unsigned resources_wanted) {
    int result;

    // ...

    result = pthread_mutex_lock(resource_mutex);
    // handle errors ...
    while (resources_available < resources_wanted) {
        result = pthread_cond_wait(resource_cv, resource_mutex);
        // handle errors ...
    }
    resources_available -= resources_wanted;
    result = pthread_mutex_unlock(resource_mutex);
    // ...
}

int release_resources(unsigned resources_released) {
    int result;

    // ...

    result = pthread_mutex_lock(resource_mutex);
    // handle errors ...
    resources_available += resources_released;
    result = pthread_cond_broadcast(resource_cv);
    // handle errors ...
    result = pthread_mutex_unlock(resource_mutex);
    // ...
}