我正在使用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;
}
答案 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();
}
};