使用线程的意外行为
Unexpected behavior using threads
我有一个函数,我想通过多线程优化。而不是用pBodies
中Body
对象的整个向量调用函数RenderBodies
,就像我这样做的:
RenderBodies(pBodies);
我想调用它4次,每次使用pBodies
向量的不同四分之一,并并行运行它们。
所以我像这样分割向量:
std::vector<Body*> Bodies1, Bodies2, Bodies3, Bodies4;
for (unsigned int i = 0; i < pBodies.size(); i += 4)
{
Bodies1.push_back(pBodies[i]);
Bodies2.push_back(pBodies[i + 1]);
Bodies3.push_back(pBodies[i + 2]);
Bodies4.push_back(pBodies[i + 3]);
}
然后使用带有新向量的线程,
std::thread t1(RenderBodies, pTarget, Bodies1, pZoom);
std::thread t2(RenderBodies, pTarget, Bodies2, pZoom);
std::thread t3(RenderBodies, pTarget, Bodies3, pZoom);
std::thread t4(RenderBodies, pTarget, Bodies4, pZoom);
t1.join();
t2.join();
t3.join();
t4.join();
但是结果是没有渲染。
问题是,RenderBodies函数没有任何问题,因为如果我使用这个:
RenderBodies(pTarget, Bodies1, pZoom);
RenderBodies(pTarget, Bodies2, pZoom);
RenderBodies(pTarget, Bodies3, pZoom);
RenderBodies(pTarget, Bodies4, pZoom);
它工作!但是它没有使用我的cpu的所有4核,所以它没有用。
为什么线程不能像预期的那样工作?
My Code inside RenderBodies():
sf::RectangleShape Temp;
mtx.lock();
for (unsigned int i = 0; i < param.pBodies.size(); i++)
{
if (param.pZoom > 1)
Temp.setSize(sf::Vector2f(param.pBodies.at(i)->mass * param.pZoom, param.pBodies.at(i)->mass * param.pZoom));
else
Temp.setSize(sf::Vector2f(param.pBodies.at(i)->mass, param.pBodies.at(i)->mass));
float AccelCoefficient = static_cast<float> (sqrt(param.pBodies.at(i)->AccelX * param.pBodies.at(i)->AccelX + param.pBodies.at(i)->AccelY * param.pBodies.at(i)->AccelY) * (20000 * _GRAV_CONST));
if (AccelCoefficient > 1)
AccelCoefficient = 1;
float Red, Green, Blue;
Blue = 1 - (AccelCoefficient);
if (AccelCoefficient < 0.2)
Red = (AccelCoefficient)* 5;
else
Red = 1;
if (AccelCoefficient < 0.5)
Green = (AccelCoefficient)* 2;
else
Green = 1;
Temp.setFillColor(sf::Color(static_cast<sf::Uint8> (Red * 255), static_cast<sf::Uint8> (Green * 255), static_cast<sf::Uint8> (Blue * 255), 128));
Temp.setPosition(static_cast<float>(param.pBodies.at(i)->posX), (static_cast<float>(param.pBodies.at(i)->posY)));
param.pTarget->draw(Temp);
}
mtx.unlock()
如果不知道RenderBodies()
函数在做什么,就不可能给出精确的答案。
然而,我的猜测是它与参数pTarget
有关,该参数将相同的值传递给所有线程,并且(从名称)是一个指针。如果是这样,这意味着你有四个线程与一个对象交互——所以线程有必要同步对该对象的访问(例如使用互斥锁或临界区)。
如果线程除了渲染pTarget
之外没有做太多的事情,同步访问它将否定多线程的大部分好处(因为,实际上,这会导致所有线程相互等待,并且所有的渲染都是顺序的)。
然而,事情就是这样。多线程并不是免费的午餐。获得性能的方法是尽量减少线程之间的同步(即使它们彼此等待)。如果你不这样做,你会得到竞争条件,所以操作可能无法正确完成——这就是你所描述的。
这就是为什么用户界面设计的一个指导方针通常是只有一个线程负责渲染窗口/屏幕。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 多线程程序中出现意外的内存泄漏
- 线程的意外输出
- 在C 中,可以检测到线程的意外终止
- C++意外的多线程行为
- 在 Linux C++的两个线程之间使用管道的错误/意外行为
- C++线程意外地打印多次相同的行
- 如何监视意外退出的线程
- 线程导致意外崩溃
- 线程意外结束.c++
- 在linux CFS调度下的C/ c++多线程场景中出现意外结果
- TBB线程池意外增加