Я создал MutexCondition класса, как этогоPthread замок
/*MutexCondtion.h file*/
#ifndef MUTEXCONDITION_H_
#define MUTEXCONDITION_H_
#include <pthread.h>
#include <stdio.h>
class MutexCondition {
private:
bool init();
bool destroy();
protected:
pthread_mutex_t m_mut;
pthread_cond_t m_con;
public:
MutexCondition(){
init();
}
virtual ~MutexCondition(){
destroy();
}
bool lock();
bool unLock();
bool wait();
bool signal();
};
#endif /* MUTEXCONDITION_H_ */
MutexCondtion.cpp файл
#include "MutexCondition.h"
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;
}
И я создал WorkHandler, который расширяет MutexCondition
#ifndef WORKHANDLER_H_
#define WORKHANDLER_H_
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <pthread.h>
#include <stdio.h>
#include <list>
#include "MutexCondition.h"
#include "Work.h"
using namespace::std;
class WorkHandler: MutexCondition {
private:
int m_maxThreads;
queue<Work*> m_workQueue;
list<pthread_t*> m_workThreadList; //Just thread IDs
pthread_t **m_workThreads;
void workLoop();
bool initThreads();
void insertWork(Work *work);
Work* getWork();
protected:
static void* runWorkThread(void* delegate);
public:
WorkHandler(int maxThreads);
virtual ~WorkHandler();
};
#endif /* WORKHANDLER_H_ */
WorkHandler.cpp файл
#include "WorkHandler.h"
WorkHandler::WorkHandler(int maxThreads) {
// TODO Auto-generated constructor stub
m_maxThreads = maxThreads;
initThreads();
}
WorkHandler::~WorkHandler() {
// TODO Auto-generated destructor stub
}
void* WorkHandler::runWorkThread(void *delegate){
printf("WorkHandler::runWorkThread called\n");
WorkHandler *ptr = reinterpret_cast<WorkHandler*>(delegate);
ptr->workLoop();
return NULL;
}
void WorkHandler::workLoop(){
printf("WorkHandler::workLoop called\n");
//WorkHandler *ptr = reinterpret_cast<WorkHandler*>(delegate);
while(1){
Work *work = getWork();
}
}
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("InitThreads, pthread_create error \n");
return false;
}
pthread_detach(*thread);
}
return true;
}
void WorkHandler::insertWork(Work* w){
printf("WorkHandler::Thread %d insertWork locking\n", pthread_self());
lock();
printf("WorkHandler::insertWork Locked and inserting int queue \n");
m_workQueue.push(w);
signal();
unLock();
}
Work* WorkHandler::getWork(){
printf("WorkHandler::getWork locking\n");
lock();
printf("WorkHandler::getWork locked\n");
while(m_workQueue.empty()){//Need while instead of If
printf("WorkHandler::getWork waiting...\n");
wait();
}
Work *work = m_workQueue.front();
printf("WorkHandler::getWork got a job\n");
m_workQueue.pop();
unLock();
return work;
}
Проблема заключается в том, что я запер переменный мьютекс в функции getWork(), как этого
printf("WorkHandler::getWork locking\n");
lock();
printf("WorkHandler::getWork locked\n");
Однако, если я вижу заявление журнала затем все темы, напечатанное этих два заявления журнала, и я думаю, что это проблема. Я не помещаю ничего в очередь, поэтому первый поток должен ждать переменную условия, которая должна сигнализироваться, и она работает нормально. Но почему другой поток может войти в область за замком, хотя первый поток заблокирован и не вызвал функцию unlock().
Мне было интересно, правильно ли это работает. Просьба дать мне знать, если вы, ребята, можете увидеть все, что мне нужно исправить. Заранее спасибо.
Как небольшая рекомендация, если вы можете использовать 'boost :: threads', это действительно упростит вашу жизнь. – GWW
Вы не должны полагаться на журналы, они могут получить буферизацию, в многопоточных журналах enviornments может не отображаться реальная картина. –
1) Поиск «Правило трех». 2) Поиск RAII. 3) Прочтите первое предложение [здесь] (http://stackoverflow.com/questions/6352280/pthread-create-error-in-c/6352434#6352434) 4) Начните использовать boost –