3

私のプログラムには sharedqueueがあり、大きく 2 つの部分に分かれています。

1 つはクラスのインスタンスを にプッシュrequestするためのものqueue、もうrequest1 つは 内の複数のオブジェクトにアクセスしてqueueこれらのオブジェクトを処理するためのものです。フィールドrequestを持つ非常に単純なクラス(テスト用)です。string req

私は 2 番目の部分に取り組んでおり、そうする中で、 onescheduling threadと multiple (私の例では two)を維持したいと考えていexecuting threadsます。

別々にしたい理由は、 の数と複数でアクセスする操作をscheduling thread減らすためです。lockunlockqueueexecuting threads

私はpthreadライブラリを使用しており、スケジューリングと実行関数は次のようになります。

void * sched(void* elem) {

    queue<request> *qr = static_cast<queue<request>*>(elem);

    pthread_t pt1, pt2;

    if(pthread_mutex_lock(&mut) == 0) {
        if(!qr->empty()) {
            int result1 = pthread_create(&pt1, NULL, execQueue, &(qr->front()));
            if (result1 != 0) cout << "error sched1" << endl;
qr->pop();
        }
        if(!qr->empty()) {
            int result2 = pthread_create(&pt2, NULL, execQueue, &(qr->front()));
            if (result2 != 0) cout << "error sched2" << endl;
qr->pop();
        }

        pthread_join(pt1, NULL);
        pthread_join(pt2, NULL);

        pthread_mutex_unlock(&mut);
    }

    return 0;
}

void * execQueue(void* elem) {

    request *r = static_cast<request*>(elem);
    cout << "req is: " << r->req << endl; // req is a string field

    return 0;
}

簡単に言えば、それぞれに実行するスレッドが 1 つあり、パラメーターexecQueueを介して渡された要求を出力するだけです。void* elem

schedで、スレッドで呼び出されmain()ます (どのように呼び出されるのか疑問に思っている場合は、main()以下のように呼び出されます)。

pthread_t schedpt;
int schresult = pthread_create(&schedpt, NULL, sched, &q);
if (schresult != 0) cout << "error sch" << endl;

pthread_join(schedpt, NULL);

そして、sched関数自体が から複数 (ここでは 2 つ)executing threadspopsを作成requestし、複数のスレッド (pthread_create と次に ptrhead_join) を呼び出しqueueて s を実行します。requestexecQueue

問題は、プログラムによる奇妙な動作です。

スレッドを作成して複数のスレッドで呼び出すことなく、サイズとキュー内の要素を確認したところ、それらはまさに期待どおりでした。

ただし、複数のスレッドでプログラムを実行すると、出力されます

1 個のアイテムがキューに入っています。2 アイテムがキューに入っています。要件は: 要件は: FIRST! �(x'�j|1��rj|p�rj|1����FIRST!�'�j|!�'�j|�'�j| P��(�(��(1� ��i|p��i|

最後の行は常に変化しています。

望ましい出力は

1 個のアイテムがキューに入っています。2 アイテムがキューに入っています。要件は: FIRST 要件は: FIRST

execQueue複数のスレッドで呼び出す方法、または間違っている方法のいずれかだと思いますがpop()、問題を理解できず、正しい使用法を参照するソースも見つかりませんでした。

これについて私を助けてください。私は初心者なので、pthread の不器用な使用についてはご容赦ください。

4

2 に答える 2

3

そして、MSVC2013のインストールに簡単なテストが必要だったという理由だけで、穏やかにサニタイズされたC ++ 11バージョンがあります:)

Coliruでライブを見る

#include <iostream>
#include <thread>
#include <future>
#include <mutex>
#include <queue>
#include <string>

struct request { std::string req; };

std::queue<request> q;
std::mutex queue_mutex;

void execQueue(request r) {
    std::cout << "req is: " << r.req << std::endl; // req is a string field
}

bool sched(std::queue<request>& qr) {
    std::thread pt1, pt2;

    {
        std::lock_guard<std::mutex> lk(queue_mutex);
        if (!qr.empty()) {
            pt1 = std::thread(&execQueue, std::move(qr.front()));
            qr.pop();
        }
        if (!qr.empty()) {
            pt2 = std::thread(&execQueue, std::move(qr.front()));
            qr.pop();
        }
    }

    if (pt1.joinable()) pt1.join();
    if (pt2.joinable()) pt2.join();

    return true;
}

int main()
{
    auto fut = std::async(sched, std::ref(q));
    if (!fut.get()) 
        std::cout << "error" << std::endl;
}

もちろん、実際にはあまり機能していません (キューにタスクがないため)。

于 2013-11-04T09:28:15.637 に答える