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

何が間違っている可能性がありますか?いくつでも。他の何かがセマフォを破壊したり、セマフォを格納するために使用されたメモリまたはセマフォへのポインタを上書きしたりしている可能性があります。もう1つの可能性は、sem_post()を何度も呼び出していて、カウンターがオーバーフローしていることです。コードサンプルが役立ちます。

于 2009-03-26T12:26:03.613 に答える
1

私たちも同じ問題を抱えていました。長い間何が起こっているのかを突き止めた結果、セマフォがバイト アラインメントが 1 に変更された構造体の内部で定義されているために問題が発生していることを発見しました (この場合はプラグマ pack(1 を使用) ) ディレクティブ)。

Linux での POSIX セマフォの実装は、futex syscall を使用します。futex のマニュアル ページによると、「操作が定義されていないか、ページの配置にエラーがある」場合、EINVAL が返されます。

私たちの場合、pragma pack(1) ディレクティブを削除するか、セマフォを構造体の最初の要素として定義することで問題が解決しました。

于 2011-03-30T18:10:54.790 に答える