1

我有一个带有信号量的队列。尽管信号量本身是有效的,但在某些时候所有调用sem_post()总是返回“无效参数”错误

信号量是 C++ 对象的私有成员,它永远不会被删除,它也可以在 gdb 中检查。我sem_getvalue()在 - 值读取之前添加了sem_post()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);
    }
}
4

2 回答 2

1

有什么问题?任何数量的东西。其他东西可能正在破坏信号量或覆盖用于存储它的内存或指向它的指针。另一种可能性是您调用 sem_post() 太多次并且计数器溢出。代码示例会有所帮助。

于 2009-03-26T12:26:03.613 回答
1

我们遇到了同样的问题,经过很长时间弄清楚可能发生的情况后,我们发现问题的发生是因为信号量是在一个字节对齐更改为 1 的结构内定义的(在本例中使用 pragma pack(1 ) 指令)。

Linux 上的 POSIX 信号量实现使用 futex 系统调用。根据 futex 手册页,当“未定义操作或页面对齐错误”时返回 EINVAL。

在我们的例子中,要么删除 pragma pack(1) 指令,要么将信号量定义为结构的第一个元素,解决了这个问题。

于 2011-03-30T18:10:54.790 回答