1

私は以前にこのトピックについて投稿しましたが、まだあまり運がありません。私はそれを私の側の悪い質問に置きました。今回は、回避しようとしている悪い動作を示す、コンパイル可能な短い例を作成しました。これが高く評価されることを願っています。

問題は、2つ(またはそれ以上)のスレッドが同じプロセスを実行するように設定されており、それらの「ID」によって、操作する変数データの部分が決まることです。現在、両方のスレッドがカウンターを更新します。

現在の出力は次のようになります。

tid = 0, var[tid] = 0
tid = 0, var[tid] = 1
tid = 0, var[tid] = 2
tid = 0, var[tid] = 3
tid = 0, var[tid] = 4
tid = 0, var[tid] = 5
tid = 0, var[tid] = 6
tid = 0, var[tid] = 7
tid = 0, var[tid] = 8
tid = 0, var[tid] = 9
tid = 1, var[tid] = 0
Press any key to continue . . .

必要な出力は次のようになります...

tid = 0, var[tid] = 0
tid = 1, var[tid] = 0
tid = 0, var[tid] = 1
tid = 1, var[tid] = 1
tid = 0, var[tid] = 2
tid = 1, var[tid] = 2
tid = 0, var[tid] = 3
tid = 1, var[tid] = 3 etc.

ここでのガイダンスは大歓迎です。

編集:意図したとおりに機能するコードで回答を更新しました。

[ここでは効率が重要であることに注意してください。できるだけ早くプロセスを完了したいと思います]

#include <iostream>  
#include <boost/thread.hpp>

int var[2];
int mT;
int mTotalSamples;
boost::mutex mCountMutex;
boost::thread *threadMap[2];

using namespace std;

void process()
{
    int tid = 1;

    // sleep for 1 seconds - just to make sure threadMap 
    // has been assigned (only ncessary for this demo).
    boost::this_thread::sleep(boost::posix_time::seconds(1));

    if (threadMap[0]->get_id() == boost::this_thread::get_id()){ tid = 0;}

    while ( mT < mTotalSamples ) 
    {
        // perform processing
        var[tid] = mT; 
        // processing complete

        mCountMutex.lock(); // (a thread waits to aquire mutex)
        cout << "tid = " << tid << ", var[tid] = " << var[tid] << endl;
        mT++;           // How to stop both threads incrementing this?      
        mCountMutex.unlock();       
    }   
}

int main()
{
    boost::thread_group threads;

    mT = 0;
    mTotalSamples = 10;

    threadMap[0] = threads.create_thread( boost::bind(&process) );
    threadMap[1] = threads.create_thread( boost::bind(&process) );

    threads.join_all();

    return 0;
}
4

2 に答える 2

1

期待される出力から判断すると、更新のたびにスレッドを同期させる必要があります。boostライブラリはboost::Barrierを提供します。これwaitは、whileループの開始時または終了時にforを配置すると、うまくいくprocessはずです。

#include <iostream>  
#include <boost/thread.hpp>

int var[2];
int mT;
int mTotalSamples;
boost::mutex mCountMutex;
boost::thread *threadMap[2];
boost::barrier bar(2);

using namespace std;

void process()
{
    int tid = 1;        

    // sleep for 2 seconds - just to make sure threadMap 
    // has been assigned (only ncessary for this demo).
    boost::this_thread::sleep(boost::posix_time::seconds(2));

    if (threadMap[0]->get_id() == boost::this_thread::get_id()){ tid = 0;}

    while ( mT < mTotalSamples ) 
    {
        // perform processing
        var[tid] = mT; 
        // processing complete


        bar.wait();
        if (threadMap[0]->get_id() == boost::this_thread::get_id())
        {
            mT++;               
            cout << "var[0] = " << var[0] << endl;
            cout << "var[1] = " << var[1] << endl;                      
        }           
        bar.wait();
    }   
}

int main()
{
    boost::thread_group threads;

    mT = 0;
    mTotalSamples = 10;

    threadMap[0] = threads.create_thread( boost::bind(&process) );
    threadMap[1] = threads.create_thread( boost::bind(&process) );

    threads.join_all();

    return 0;
}
于 2012-07-04T21:21:52.243 に答える
1

これint mT;をprocess()でローカルにします-グローバルではありません。または、int mT[2]; ミューテックスは必要ありません。

于 2012-07-04T21:24:48.453 に答える