【发布时间】:2010-08-16 08:56:16
【问题描述】:
我有这个要求,我必须将 POSIX 信号量的值增加 1 以上。
显然,POSIX 规范中没有办法做到这一点。没有类似于 sem_getvalue() 的 sem_setvalue()。我不想仅仅因为这个约束而回到 System V 信号量。
有没有其他方法可以做到这一点?还是我必须采用 System V 的方式?
我在 GNU/Linux 上用 C 语言编程。
非常感谢。
【问题讨论】:
我有这个要求,我必须将 POSIX 信号量的值增加 1 以上。
显然,POSIX 规范中没有办法做到这一点。没有类似于 sem_getvalue() 的 sem_setvalue()。我不想仅仅因为这个约束而回到 System V 信号量。
有没有其他方法可以做到这一点?还是我必须采用 System V 的方式?
我在 GNU/Linux 上用 C 语言编程。
非常感谢。
【问题讨论】:
我有这个要求,我必须将 POSIX 信号量的值增加 1 以上。 有没有其他方法可以做到这一点?还是我必须采用 System V 的方式?
那么你的问题到底是什么?如何实现接口不支持的东西?或者如何使用 POSIX 创建一个行为类似于 semaphore 的结构?
如果是稍后,在使用 SysV 之类的重炮之前,您始终可以使用 pthread_mutex_t/pthread_cond_t 对来实现几乎任何多线程同步原语,包括信号量。
例如,未经测试:
typedef cool_sem {
pthread_mutex_t guard;
pthread_cond_t cond;
int count;
} cool_sem_t;
void init( cool_sem_t *s )
{
pthread_mutex_init( &s->guard, 0 );
pthread_cond_init( &s->cond, 0 );
s->S = 0;
}
void incr( cool_sem_t *s, unsigned delta )
{
assert( s );
pthread_mutex_lock( &s->guard );
s->S += delta;
pthread_cond_broadcast( &s->cond );
pthread_mutex_unlock( &s->guard );
}
void decr( cool_sem_t *s, unsigned delta )
{
assert( s );
pthread_mutex_lock( &s->guard );
do {
if (s->S >= delta) {
s->S -= delta;
break;
}
pthread_cond_wait( &s->cond, &s->guard );
} while (1);
pthread_mutex_unlock( &s->guard );
}
【讨论】:
count 不反映在信号量上等待的进程数。并且decr() 值较低的delta 值的进程将优先于delta 值较高的进程,这可能会导致饥饿。
semctl 和semop 是您所需要的。在 smectl 中使用 GETVAL SETVAL 获取 getter 和 setter。在使用 semop 时将 sembuf 结构中的 sem_op 设置为您想要对信号量执行的操作。见人了解更多。
【讨论】:
不,在使用sem_t 时没有这样的选择。如果您还没有这样做,请阅读 linux 上的 sem_overview 手册页。列出的所有调用都是您可以获得的:初始化为特定值、递增和递减一。
【讨论】:
如果这是完整的规范,我认为您的老师希望您提出一种机制,允许您以原子方式将信号量增加不止一个。所以我猜你的任务之一是同步增量。
【讨论】: