2

を使用してマルチスレッドがどのように機能するかを理解するために、小さな C++ プログラムをコーディングしましたstd::thread。これが私のプログラム実行のステップです:

  1. クラス 'Toto' に含まれる一意の値 '42' を持つ整数の 5x5 マトリックスの初期化 (メインで初期化)。
  2. 初期化された 5x5 マトリックスを出力します。
  3. std::vector5 スレッドの宣言。
  4. すべてのスレッドをそれぞれのタスク (threadTaskメソッド) にアタッチします。各スレッドはstd::vector<int>インスタンスを操作します。
  5. 私はすべてのスレッドに参加します。
  6. 5x5 行列の新しい状態を出力します。

出力は次のとおりです。

42 42 42 42 42
42 42 42 42 42
42 42 42 42 42
42 42 42 42 42
42 42 42 42 42

42 42 42 42 42
42 42 42 42 42
42 42 42 42 42
42 42 42 42 42
42 42 42 42 42

そのはず :

42 42 42 42 42
42 42 42 42 42
42 42 42 42 42
42 42 42 42 42
42 42 42 42 42

0 0 0 0 0
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4

コードサンプルは次のとおりです。

#include <iostream>
#include <vector>
#include <thread>

class       Toto
{
public:
    /*
    ** Initialize a 5x5 matrix with the 42 value.
    */
    void    initData(void)
    {
        for (int y = 0; y < 5; y++) {
            std::vector<int> vec;

            for (int x = 0; x < 5; x++) {
                vec.push_back(42);
            }
            this->m_data.push_back(vec);
        }
    }

    /*
    ** Display the whole matrix.
    */
    void    printData(void) const
    {
        for (int y = 0; y < 5; y++) {
            for (int x = 0; x < 5; x++) {
                printf("%d ", this->m_data[y][x]);
            }
            printf("\n");
        }
        printf("\n");
    }

    /*
    ** Function attached to the thread (thread task).
    ** Replace the original '42' value by the another one.
    */
    void    threadTask(std::vector<int> &list, int value)
    {
        for (int x = 0; x < 5; x++) {
            list[x] = value;
        }
    }

    /*
    ** Return a sub vector reference according to the range.
    */

    std::vector<int>    &getDataByRange(int range)
    {
        return (this->m_data[range]);
    }

    private:
        std::vector<std::vector<int> > m_data;
};

int         main(void)
{
    Toto    toto;

    toto.initData();

    toto.printData(); //Display the original 5x5 matrix (first display).

    std::vector<std::thread> threadList(5); //Initialization of vector of 5 threads.

    for (int i = 0; i < 5; i++) {  //Threads initializationss

        std::vector<int> &vec = toto.getDataByRange(i); //Get each sub-vectors reference.
        threadList.at(i) = std::thread(&Toto::threadTask, toto, vec, i); //Each thread will be attached to a specific vector.
    }

    for (int j = 0; j < 5; j++) {
        threadList.at(j).join();
    }

    toto.printData(); //Second display.
    getchar();

    return (0);
}

ただし、メソッドthreadTaskで変数を出力するlist[x]と、出力は正しくなります。threadTaskprintData() 呼び出しがメインスレッドにあり、メソッドが独自のスレッド(メインスレッドではない)で実行されるため、関数の表示が正しいため、メインで正しいデータを印刷できないと思います。奇妙なことに、親プロセスで作成されたすべてのスレッドが、この親プロセスのデータを変更できないということですか? コードで何かを忘れていると思います。私は本当に迷っています。誰でも私を助けることができますか?よろしくお願いいたします。

4

2 に答える 2

3

これを書いているあなたの選択の多くが、あなたの仕事を必要以上に難しくしているように私には思えます。特に、あなたのtotoクラスは (私には) クライアント コードを単純ではなく複雑にしているように見え、操作するデータをカプセル化できません。これを行う場合、次の一般的な行に沿ってコードを書くと思います。

#include <iostream>
#include <vector>
#include <thread>
#include <algorithm>

std::ostream &operator<<(std::ostream &os, std::vector<int> const &d) {
    for (auto const &v : d)
        os << v << "\t";
    return os;
}

std::ostream &operator<<(std::ostream &os, std::vector <std::vector<int>> const &d) {
    for (auto const &v : d)
        os << v << "\n";
    return os;
}

int main(void) {
    std::vector<std::vector<int>> d(5, std::vector<int>(5, 42));

    std::cout << d;

    std::vector<std::thread> threads;

    for (int i = 0; i < 5; i++)
        threads.emplace_back([i, &d]() {std::fill(d[i].begin(), d[i].end(), i); });

    std::for_each(threads.begin(), threads.end(), [](std::thread &t){t.join(); });

    std::cout << "\n" << d;
}
于 2013-07-02T18:03:23.890 に答える
2

問題を解決しました。すべては行から来ます:

threadList.at(i) = std::thread(&Toto::threadTask, toto, **vec**, i);

である必要があります:

threadList.at(i) = std::thread(&Toto::threadTask, toto, **&vec**, i);

私の関数「threadTask」は、最初のパラメーターでポインター(参照ではない)を取る必要があります。

void    threadTask(std::vector<int> *list, int value)
    {
        printf("b=%p\n", list);
        getchar();
        for (int x = 0; x < 5; x++) {
            (*list)[x] = value;
        }
    }

この例が誰かの役に立てば幸いです。

于 2013-07-02T17:49:57.387 に答える