2

I'm working on learning to use boost threads. I'm trying to make a simple program where I feed numbers to a queue that is available on both threads and output it on the worker thread.

I made it so that the worker thread shuts down if I feed it a 1.

The problem is when I call join, my main thread just sits there and waits for the worker thread to be finished. I do not want this. I want main to keep executing in parallel to the worker thread.

template<typename Data>
class concurrent_queue
{
private:
    std::queue<Data> the_queue;
    mutable boost::mutex the_mutex;
    boost::condition_variable the_condition_variable;
public:
    void push(Data const& data)
    {
        boost::mutex::scoped_lock lock(the_mutex);
        the_queue.push(data);
        lock.unlock();
        the_condition_variable.notify_one();
    }

    bool empty() const
    {
        boost::mutex::scoped_lock lock(the_mutex);
        return the_queue.empty();
    }

    bool try_pop(Data& popped_value)
    {
        boost::mutex::scoped_lock lock(the_mutex);
        if(the_queue.empty())
        {
            return false;
        }

        popped_value=the_queue.front();
        the_queue.pop();
        return true;
    }

    void wait_and_pop(Data& popped_value)
    {
        boost::mutex::scoped_lock lock(the_mutex);
        while(the_queue.empty())
        {
            the_condition_variable.wait(lock);
        }

        popped_value=the_queue.front();
        the_queue.pop();
    }

};

void workerFunc(concurrent_queue<int>* q )  
{  
    while(true)
    {
        while(!q->empty())
        {
            int p = -1;
            q->wait_and_pop(p);
            std::cout << p;

            if(p == 1)
            {
                return;
            }
        }
    }
}  

int main(int argc, char* argv[])  
{  
    concurrent_queue<int> m_q;
    std::cout << "main: startup" << std::endl;  

    boost::thread workerThread(workerFunc,&m_q);  

    std::cout << "main: waiting for thread" << std::endl;  

    m_q.push(6);
    m_q.push(11);
    workerThread.join();
    m_q.push(99); //will not reach here
    std::cout << "main: done" << std::endl;  

    return 0;  
} 

Thanks

I want the thread to be active and running and only process numbers when it has some that could be given at any time by the main thread.

4

1 回答 1

2

join()函数等待附加线程完成,因为它应该。如果您的目的是让该线程在程序的整个生命周期内(或直到您将 a 推入队列)保持运行,那么您的主线程没有理由调用join() 它所在的位置。1

如果您根本没有那个线程,那么当对象超出范围join()时,线程将分离。workerThread这几乎肯定不是你想要的。通常,多线程程序会在从main. 在您的情况下,您需要1在调用之前专门向您的线程发出信号(通过将 a 推送到您的队列中)join()以使您的程序干净地退出。

这是一个例子:

int main(int argc, char* argv[])  
{  
    concurrent_queue<int> m_q;
    std::cout << "main: startup" << std::endl;  

    boost::thread workerThread(workerFunc,&m_q);  

    std::cout << "main: waiting for thread" << std::endl;  

    m_q.push(6);
    m_q.push(11);

    // not ready for this yet...
    // workerThread.join();

    m_q.push(99);

    boost::this_thread::sleep(1000);

    m_q.push(50);
    m_q.push(30);

    std::cout << "main: done" << std::endl;  

    m_q.push(1);
    workerThread.join();

    return 0;  
}
于 2012-05-10T15:43:30.963 回答