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 回答