我有一个带信号量的队列。在某些时候,sem_post()
的所有调用总是返回'无效参数'错误,尽管信号量本身是有效的
信号量是C ++对象的私有成员,永远不会被删除,也可以在gdb中进行检查。我在sem_getvalue()
之前添加了sem_post()
- 值读取正常,然后在sem_post()
上失败。可能有什么不对?
CThreadQueue::CThreadQueue(int MaxSize) :
_MaxSize(MaxSize)
{
sem_init(&_TaskCount, 0, 0)
pthread_mutex_init(&_Mutex, 0);
pthread_create(&_Thread, NULL, CThreadQueue::StartThread, this);
}
CThreadQueue::~CThreadQueue()
{
pthread_kill(_Thread, SIGKILL);
sem_destroy(&_TaskCount);
}
int CThreadQueue::AddTask(CThreadTask Task)
{
pthread_mutex_lock(&_Mutex);
_Queue.push_back(TempTask);
sem_post(&_TaskCount)
pthread_mutex_unlock(&_Mutex);
return 0;
}
void *CThreadQueue::StartThread(void *Obj)
{
((CThreadQueue*)Obj)->RunThread();
return NULL;
}
//runs in a separate thread
void CThreadQueue::RunThread()
{
CThreadQueue::CTask Task;
while(1) {
sem_wait(&_TaskCount);
pthread_mutex_lock(&_Mutex);
Task = _Queue.front();
_Queue.pop_front();
pthread_mutex_unlock(&_Mutex);
if (Task.Callee != NULL)
Task.Callee->CallBackFunc(NULL, Task.CallParam);
}
}
答案 0 :(得分:1)
可能有什么不对?任何数量的东西。其他东西可能会破坏信号量或覆盖用于存储信号量的内存或指向它的指针。另一种可能性是你多次调用sem_post()并且计数器溢出。代码示例会有所帮助。
答案 1 :(得分:1)
我们遇到了同样的问题,经过很长一段时间搞清楚可能发生的事情,我们发现问题的发生是因为信号量是在一个结构中定义的,该结构的字节对齐方式改为1(在这种情况下使用pragma) pack(1)指令)。
Linux上的POSIX信号量实现使用futex系统调用。根据futex手册页,当“未定义操作或页面对齐错误”时,将返回EINVAL。
在我们的例子中,删除pragma pack(1)指令或将信号量定义为结构的第一个元素,解决了这个问题。