2

私はブーストスレッドの使い方を学ぶことに取り組んでいます。両方のスレッドで使用可能なキューに数値をフィードし、それをワーカースレッドに出力する単純なプログラムを作成しようとしています。

1をフィードするとワーカースレッドがシャットダウンするようにしました。

問題は、joinを呼び出すと、メインスレッドがそこにとどまり、ワーカースレッドが終了するのを待つことです。これいらない。mainをワーカースレッドと並行して実行し続けたい。

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

ありがとう

スレッドをアクティブにして実行し、メインスレッドからいつでも指定できる番号がある場合にのみ番号を処理するようにします。

4

1 に答える 1

2

関数は、接続されたスレッドが終了するのjoin()を待ちます。プログラムの存続期間中(またはキューにプッシュするまで)そのスレッドを実行し続けることが目的である場合、メインスレッドが呼び出し元join() の場所を呼び出す理由はありません。1

join()そのスレッドをまったく実行しないと、workerThreadオブジェクトがスコープ外になるとスレッドが切り離されます。これはほぼ間違いなくあなたが望むものではありません。通常、マルチスレッドプログラムは、から戻る前にすべてのスレッドをjoin()しmainます。あなたの場合、あなたはあなたのプログラムをきれいに終了させるため1に呼び出す前にあなたのスレッドに(あなたのキューにプッシュすることによって)具体的に合図する必要があります。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 に答える