在单独的线程上同时调用函数

时间:2011-06-20 07:56:10

标签: c++ pthreads

我正在进行网络编程,我已经创建了一个线程池。它基本上有一个带有互斥锁和条件变量的队列,并且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文件

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

1 个答案:

答案 0 :(得分:0)

  问题是,如果我打电话给   然后从子线程的函数   只允许一个线程工作

如果你把这个假设建立在你的printf上,那么你错了。工作线程可能会在新项目放入队列之前完成它的工作。这创造了可能性,相同的功能将连续拾取两个项目。

其他线程无法等待工作,因为在getWork()返回后没有任何东西可以阻止它们。