2011-06-20 64 views
0

我正在進行網絡編程,並創建了一個線程池。它基本上具有互斥鎖和條件變量的隊列,5個子線程競爭從隊列中獲取工作。看起來像使用條件變量鎖定和解鎖正確工作。在單獨的線程上同時調用一個函數

但問題是,如果我從子線程調用一個函數,那麼只允許一個線程在函數(fromByte)上工作。例如,如果線程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函數上工作,並且如果線程完成,則其他線程可以在該函數中工作。換句話說,如果一個線程當前在該函數中,則其他線程將等待線程完成工作。

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函數。如何修復我的代碼,以便子線程可以同時處理該函數。在此先感謝..

編輯

我鎖定和解鎖這樣

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; 
} 

而且,這個類擴展MutexdCondtion類我創建 MutexCondition.cpp文件

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

問題是,如果我從子線程調用 函數那麼 只允許一個線程工作

如果你基於這個假設你的printf,那麼你是錯的。工作線程可能會在新項目放入隊列之前完成工作。這創造了可能性,相同的功能將連續挑選兩個項目。

沒有辦法讓其他線程等待工作,因爲getWork()返回後沒有任何東西阻止它們。

+0

噢,這可能是原因..如果我在workLoop中設置了隨機數量的睡眠,那麼我認爲我應該看到多於一個線程在功能的內部.. – user800799

+0

最好是長時間睡眠在線程中,並立即推送隊列中的兩個項目。 – arrowd