【发布时间】:2009-03-26 10:57:46
【问题描述】:
我有一个带有信号量的队列。在某些时候,所有对sem_post() 的调用总是返回“无效参数”错误,尽管信号量本身是有效的
信号量是 C++ 对象的私有成员,永远不会被删除,它也可以在 gdb 中检查。我在sem_post() 之前添加了sem_getvalue() - 该值显示为OK,然后在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);
}
}
【问题讨论】:
-
你能生成一个重现问题的测试程序吗?
-
嗨,杰克,你知道发生了什么吗?谢谢!
-
对不起,大卫。我无法重现该问题。那是很久以前的事了,从 diff 我生气的唯一一件事就是检查 sem_wait()
-
像这样: int SemResult = sem_wait(&_TaskCount); if (SemResult != 0) { if (errno != EINTR) //EINTR 正常:可能是 gdb LOG_ERRNO