2009-03-26 17 views
1

私はセマフォを持つキューを持っています。特定の時点で、sem_post()へのすべての呼び出しは、セマフォ自体が有効であるにもかかわらず、常に「無効な引数」エラーを返します。sem_post()が有効なセマフォで失敗する

セマフォは削除されないC++オブジェクトのプライベートメンバーで、gdbで検査することもできます。私は、の前に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); 
    } 
} 
+0

問題を再現するテストプログラムを作成できますか? –

+0

こんにちはジャック、何が起こっているのか調べましたか?ありがとうございました! –

+0

申し訳ありません、David。私は問題を再現できません。それはずっと前です。私が追加した唯一のことは、sem_wait()をチェックすることでした。これは次のように – jackhab

答えて

1

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

+0

同じ問題が発生していますが、何が起こっているのか分かりません。私はカウンタがオーバーフローしておらず、メモリが正しいことを確認しましたが、sem_postが-1を返しますが、カウンタが正しく増加しているということはもっと奇妙です... –

1

私たちは同じ問題を抱えていましたが、何が起こっているのかを考え出した後、セマフォーがバイト配列が1に変更された構造体内で定義されていたためプラグマパック(1)指令)。

LinuxでのPOSIXセマフォの実装では、futexのシステムコールが使用されます。 futexのマニュアルページによると、 "操作が定義されていないか、ページの位置合わせにエラーがある"ときにEINVALが返されます。

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

+0

+1なぜパック構造* *決して使用しないでください**。 –

関連する問題