从线程中获取本机句柄?

时间:2013-01-22 02:33:21

标签: c++ windows multithreading winapi c++11

我正在使用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;
    }

3 个答案:

答案 0 :(得分: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;
}

试试。

答案 1 :(得分:2)

0xcccccccc表示“变量未初始化”。您的代码中存在线程争用错误。线程在分配“mT”变量之前开始运行。您需要额外的同步来阻止线程,直到分配完成,这样您就可以安全地使用mT。这样也可以确保新线程看到更新的mT值,多核机器上需要内存屏障。

答案 2 :(得分: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();
    }
};