2011-06-20 17 views
0

私はネットワークプログラミングで作業しており、スレッドプールを作成しました。基本的にmutexロックと条件変数を持つキューがあり、5つの子スレッドが競合してキューから作業を取得します。それは、条件変数でロックやロック解除を正しく実行しているようです。別のスレッドで同時に関数を呼び出す

しかし、問題は、私が子スレッドから関数を呼び出すと、関数(fromByte)に対して1つのスレッドしか動作できないということです。たとえば、スレッド1が関数を呼び出した場合、もう一方のスレッドは関数に入ることができません。

void WorkHandler::workLoop(){ 
    printf("WorkHandler::workLoop, called\n"); 

    while(m_workHandlerRun){ 
     Work *work = getWork(); 
     char *pdata = work->getMsg(); 
     /* 
     * Get type only 
     */ 
     unsigned char type = pdata[0]; 

     printf("WorkHandler::workLoop, type %d\n", type); 

     Packet *packet = m_packetFactory->createInstance(static_cast<PACKET_TYPES>(type)); 
     packet->fromByte(pdata); 
    } 
} 

これは、子スレッドが実行されており、工場から適切なクラスインスタンスを取得した後にfromByte()を呼び出す作業ループです。私がログステートメントを見ると、fromByte関数で1つのスレッドしか動作することができず、スレッドが終了すると他のスレッドがその関数で動作することができます。言い換えれば、スレッドが現在機能している場合、他のスレッドはスレッドが作業を終了するまで待機する。

bool WorkHandler::initThreads(){ 

    for(int i=0; i < m_maxThreads; i++){ 
     pthread_t *thread(new pthread_t); 
     m_workThreadList.push_back(thread); 

     if(pthread_create(thread, NULL, runWorkThread, reinterpret_cast<void *>(this))!=0){ 
      perror("WorkHandler::initThreads, pthread_create error \n"); 
      return false; 
     } 

     pthread_detach(*thread); 
    } 

    return true; 
} 

これはスレッドを生成する方法で、runWorkThreadはworkLoop関数を呼び出す静的メソッドです。子スレッドが同時に機能するようにコードを修正するにはどうしたらいいですか?事前に感謝..

編集

私はまた、このクラスはMutexdCondtionクラスを拡張し、私は

bool MutexCondition::init(){ 
    printf("MutexCondition::init called\n"); 
    pthread_mutex_init(&m_mut, NULL); 
    pthread_cond_init(&m_con, NULL); 
    return true; 
} 

bool MutexCondition::destroy(){ 
    pthread_mutex_destroy(&m_mut); 
    pthread_cond_destroy(&m_con); 
    return true; 
} 

bool MutexCondition::lock(){ 
    pthread_mutex_lock(&m_mut); 
    return true; 
} 

bool MutexCondition::unLock(){ 
    pthread_mutex_unlock(&m_mut); 
    return true; 
} 

bool MutexCondition::wait(){ 
    pthread_cond_wait(&m_con, &m_mut); 
    return true; 
} 

bool MutexCondition::signal(){ 
    pthread_cond_signal(&m_con); 
    return true; 
} 
+0

これはすべてireleaventです。どのようにメソッドをロックしていますか? –

答えて

0
MutexCondition.cppファイルを作成し、ロックし、この

void WorkHandler::addWork(Work* w){ 
    printf("WorkHandler::insertWork Thread, insertWork locking \n"); 
    lock(); 
    printf("WorkHandler::insertWork Locked, and inserting into queue \n"); 
    m_workQueue.push(w); 
    signal(); 
    unLock(); 
} 

Work* WorkHandler::getWork(){ 
    printf("WorkHandler::getWork, locking (tid : %lu) \n", pthread_self()); 
    lock(); 
    printf("WorkHandler::getWork, locked (tid : %lu) \n", pthread_self()); 
    while(m_workQueue.empty()){//Need 'while' instead of 'If' 
     printf("WorkHandler::getWork, waiting... (tid : %lu) \n", pthread_self()); 
     wait(); 
     printf("WorkHandler::getWork, waiting DONE (tid : %lu) \n", pthread_self()); 
    } 
    Work *work = m_workQueue.front(); 
    printf("WorkHandler::getWork, got a job (tid : %lu) \n", pthread_self()); 
    m_workQueue.pop(); 
    unLock(); 

    return work; 
} 

のようにロックを解除しています

問題は、子スレッドから 関数を呼び出すと 1つのスレッドのみが許可されています

この仮定をあなたのprintfに基づいていれば、間違っています。作業中のスレッドは、新しいアイテムがキューに置かれる前に作業を終了する可能性があります。これにより、同じ機能が2つの項目を連続して取得する可能性が生じます。

getWork()が復帰した後に他のスレッドをブロックするものがないため、他のスレッドが動作するのを待つ方法はありません。

+0

ああ、それは理由かもしれない。私はworkLoopで睡眠のランダムな量を設定すると、私は複数のスレッドが関数の内部にあることを確認する必要があると思う。 – user800799

+0

長い睡眠を置く方が良いスレッドで即座に2つのアイテムをキューにプッシュします。 – arrowd

関連する問題