hha*_*fez 10 unix macos posix semaphore
我正在尝试移植一个使用Semaphores到Mac OS X的项目(从linux)但是在Mac OS X上没有实现一些posix信号量
我在这个港口遇到的那个是 sem_timedwait()
我对信号量知之甚少,但是从手册页sem_wait()似乎接近sem_timedwait并且实现了
从手册页
sem_timedwait()function应锁定函数中
semas所引用的信号量sem_wait().但是,如果在
不等待另一个进程或线程
通过执行sem_post()函数来解锁信号量的情况下无法锁定信号量,则
在指定的超时到期时应终止此等待
从我对semphores如何工作的有限理解,我可以看到sem_timedwait()更安全,但我仍然应该能够使用sem_wait()
它是否正确?如果不是我还有其他选择......
谢谢
超时很可能对算法的运行很重要.因此,使用sem_wait()可能不起作用.
您可以使用sem_trywait(),在所有情况下立即返回.然后,您可以循环,并使用您选择的休眠间隔,每次递减总超时,直到您用完超时或获取信号量.
一个更好的解决方案是重写算法以使用条件变量,然后您可以使用pthread_cond_timedwait()来获得适当的超时.
我曾经在 OSX 上使用命名信号量,但现在 sem_timedwait 不可用,并且 sem_init 和朋友已被弃用。我使用 pthread 互斥体和条件实现了信号量,如下所示,这对我有用(OSX 10.13.1)。您可能必须制作一个句柄与结构表,并查找 sem_t 类型,如果它不能在其中保存 ptr (即指针是 64 位而 sem_t 是 32?)
#ifdef __APPLE__
typedef struct
{
pthread_mutex_t count_lock;
pthread_cond_t count_bump;
unsigned count;
}
bosal_sem_t;
int sem_init(sem_t *psem, int flags, unsigned count)
{
bosal_sem_t *pnewsem;
int result;
pnewsem = (bosal_sem_t *)malloc(sizeof(bosal_sem_t));
if (! pnewsem)
{
return -1;
}
result = pthread_mutex_init(&pnewsem->count_lock, NULL);
if (result)
{
free(pnewsem);
return result;
}
result = pthread_cond_init(&pnewsem->count_bump, NULL);
if (result)
{
pthread_mutex_destroy(&pnewsem->count_lock);
free(pnewsem);
return result;
}
pnewsem->count = count;
*psem = (sem_t)pnewsem;
return 0;
}
int sem_destroy(sem_t *psem)
{
bosal_sem_t *poldsem;
if (! psem)
{
return EINVAL;
}
poldsem = (bosal_sem_t *)*psem;
pthread_mutex_destroy(&poldsem->count_lock);
pthread_cond_destroy(&poldsem->count_bump);
free(poldsem);
return 0;
}
int sem_post(sem_t *psem)
{
bosal_sem_t *pxsem;
int result, xresult;
if (! psem)
{
return EINVAL;
}
pxsem = (bosal_sem_t *)*psem;
result = pthread_mutex_lock(&pxsem->count_lock);
if (result)
{
return result;
}
pxsem->count = pxsem->count + 1;
xresult = pthread_cond_signal(&pxsem->count_bump);
result = pthread_mutex_unlock(&pxsem->count_lock);
if (result)
{
return result;
}
if (xresult)
{
errno = xresult;
return -1;
}
}
int sem_trywait(sem_t *psem)
{
bosal_sem_t *pxsem;
int result, xresult;
if (! psem)
{
return EINVAL;
}
pxsem = (bosal_sem_t *)*psem;
result = pthread_mutex_lock(&pxsem->count_lock);
if (result)
{
return result;
}
xresult = 0;
if (pxsem->count > 0)
{
pxsem->count--;
}
else
{
xresult = EAGAIN;
}
result = pthread_mutex_unlock(&pxsem->count_lock);
if (result)
{
return result;
}
if (xresult)
{
errno = xresult;
return -1;
}
return 0;
}
int sem_wait(sem_t *psem)
{
bosal_sem_t *pxsem;
int result, xresult;
if (! psem)
{
return EINVAL;
}
pxsem = (bosal_sem_t *)*psem;
result = pthread_mutex_lock(&pxsem->count_lock);
if (result)
{
return result;
}
xresult = 0;
if (pxsem->count == 0)
{
xresult = pthread_cond_wait(&pxsem->count_bump, &pxsem->count_lock);
}
if (! xresult)
{
if (pxsem->count > 0)
{
pxsem->count--;
}
}
result = pthread_mutex_unlock(&pxsem->count_lock);
if (result)
{
return result;
}
if (xresult)
{
errno = xresult;
return -1;
}
return 0;
}
int sem_timedwait(sem_t *psem, const struct timespec *abstim)
{
bosal_sem_t *pxsem;
int result, xresult;
if (! psem)
{
return EINVAL;
}
pxsem = (bosal_sem_t *)*psem;
result = pthread_mutex_lock(&pxsem->count_lock);
if (result)
{
return result;
}
xresult = 0;
if (pxsem->count == 0)
{
xresult = pthread_cond_timedwait(&pxsem->count_bump, &pxsem->count_lock, abstim);
}
if (! xresult)
{
if (pxsem->count > 0)
{
pxsem->count--;
}
}
result = pthread_mutex_unlock(&pxsem->count_lock);
if (result)
{
return result;
}
if (xresult)
{
errno = xresult;
return -1;
}
return 0;
}
#endif
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12921 次 |
| 最近记录: |