Я работаю над сетевым программированием и создал пул потоков. В основном он имеет очередь с блокировкой мьютекса и переменной условия, и 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 () после получения соответствующего экземпляра класса от фабрики. Если я вижу оператор log, то только одна нить может работать с функцией 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 file
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;
}