2

私は VS2012 を使用しており、実行中のスレッド内からスレッドの優先順位を設定したいと考えています。目標は、すべてのスレッドを最高の優先度の状態で初期化することです。HANDLEこれを行うには、スレッドにアクセスしたいと思います。

オブジェクトに対応するポインタへのアクセスに問題がありthreadます。

これは可能ですか?

呼び出し元のメイン スレッドからは、ポインターは有効であり、C++11 スレッドからは に設定されCCCCCCCCます。意味のないメモリの場所を予測どおり逆参照すると、クラッシュが発生します。

以下のコードは、問題を示す単純化されたバージョンです。

#include "stdafx.h"
#include <Windows.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <atomic>
using namespace std;
class threadContainer
    {
    thread* mT;
    condition_variable* con;
    void lockMe()
        {
        mutex m;
        unique_lock<std::mutex> lock(m);
        con->wait(lock);//waits for host thread
        cout << mT << endl;//CCCCCCCC
        auto h = mT->native_handle();//causes a crash
        con->wait(lock);//locks forever
        }
    public:
        void run()
            {
            con = new condition_variable();
            mT = new thread(&threadContainer::lockMe,*this);
            cout << mT << endl; //00326420
            con->notify_one();// Without this line everything locks as expected
            mT->join();
            }
    };
int _tmain(int argc, _TCHAR* argv[])
    {
    threadContainer mContainer;
    mContainer.run();
    return 0;
    }
4

3 に答える 3

3
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <atomic>
#include <thread>

class threadContainer {
   std::thread* mT;
  std::mutex m;
  void lockMe() {
    // wait for mT to be assigned:
    {
      std::unique_lock<std::mutex> lock(m);
    }
    std::cout << "lockMe():" << mT << "\n";
    auto h = mT->native_handle();//causes a crash
    std::cout << "Done lockMe!\n";
  }
  public:
    void run() {
      // release lock only after mT assigned:
      {
        std::unique_lock<std::mutex> lock(m);
        mT = new std::thread( [&](){ this->lockMe(); } );
      }
      std::cout << "run():" << mT << "\n"; //00326420
      mT->join();
    }
};

int main() {
  threadContainer mContainer;
  mContainer.run();
  return 0;
}

それを試してみてください。

于 2013-01-22T04:27:23.570 に答える
2

0xcccccccc は「変数が初期化されていない」ことを意味します。コードにスレッド競合バグがあります。スレッドは、「mT」変数が割り当てられる前に実行を開始します。安全に mT を使用できるように、割り当てが完了するまでスレッドをブロックするために追加の同期が必要になります。これにより、新しいスレッドが mT の更新された値を認識できるようになります。マルチコア マシンではメモリ バリアが必要です。

于 2013-01-22T02:53:10.807 に答える
1

condition_variable これはと を使用したコード例ですmutex

class threadContainer
{
    std::thread* mT;
    std::mutex m;
    std::condition_variable cv;
    bool flag;
    void lockMe() {
        // 1. you must acquire lock of mutex.
        unique_lock<std::mutex> lk(m);
        // 2. and wait on `cv` for `flag==true`
        cv.wait(lk, [&]{ return flag; });
        cout << mT << endl;
        auto h = mT->native_handle();
    }
public:
    void run()
    {
        flag = false;
        mT = new std::thread( [&](){ this->lockMe(); } );
        {
            // 3. set `flag` and signal `cv`
            lock_guard<decltype(m)> lk(m);
            cout << mT << endl;
            flag = true;
            cv.notify_one();
        }
        mT->join();
    }
};

本当にやりたいことが「すべてのスレッドを優先度の最も高い状態で初期化する」場合は、この単純化されたコードはどうですか? とにかく、スレッドの優先度の変更はプラットフォームに依存し、C++ 標準ライブラリから外れています。

class threadContainer
{
    std::thread thd;
    void work() {
        // (1) change thread priority itself
        ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
        // do something...
    }
public:
    void run()
    {
        thd = std::thread( [&](){ this->work(); } );
        // (2) or change thread priority from outside
        ::SetThreadPriority(thd.native_handle(), THREAD_PRIORITY_HIGHEST);
        thd.join();
    }
};
于 2013-01-23T10:55:11.883 に答える