SFML线程没有并行运行

时间:2012-09-17 14:46:31

标签: c++ multithreading sfml

我正在尝试学习线程和互斥体是如何工作的,但是我现在遇到了一个混乱的漏洞,我从官方的SFML 1.6教程中获取了以下代码:

#include <SFML/System.hpp>
#include <iostream>

void ThreadFunction(void* UserData)
{
    // Print something...
    for (int i = 0; i < 10; ++i)
        std::cout << "I'm the thread number 1" << std::endl;
}

int main()
{
    // Create a thread with our function
    sf::Thread Thread(&ThreadFunction);

    // Start it !
    Thread.Launch();

    // Print something...
    for (int i = 0; i < 10; ++i)
        std::cout << "I'm the main thread" << std::endl;

    return EXIT_SUCCESS;
}

它说

  

因此两个线程的文本将同时显示。

然而,这没有发生,它首先执行第一个线程然后第二个线程,它们不应该同时运行吗?我在Windows XP SP3上使用Codeblocks IDE,运行SFML 1.6。我做错了什么,或者我误解了它们是如何工作的?从我的角度来看,线程应该同时执行,因此输出应该类似于

来自帖子1的文字 线程2中的文本 线程1中的文本 等等“

enter image description here

1 个答案:

答案 0 :(得分:4)

  

......他们不应该同时跑?

嗯,这取决于。

如果您有两个或更多核心,则可能同时运行。

即使您拥有可用的硬件,也可以由您的操作系统决定如何安排线程:如果您想鼓励您的操作系统交错两个线程(您可以&# 39; t强制它没有更多的工作),尝试向你的循环添加sleepnanosleepyield调用(确切的原语取决于你的平台)。


如果它可以帮助您建立关于内核如何以及为何做出调度决策的直觉,请注意大多数CPU架构将保留大量的状态(分支预测表,数据和指令缓存),这些状态非常适合优化单线程执行。

因此,让给定的线程尽可能长时间地在给定的核心上运行,以最大限度地减少可避免的上下文切换,缓存未命中和错误预测的次数,通常会更有效。

现在,时间片经常被用作每个单独进程的最佳吞吐量与最佳延迟或对外部事件的响应之间的权衡。线程可能会阻塞(通过等待外部事件,例如用户输入或设备I / O,因为它显式与另一个线程同步,或明确地睡眠或产生),在这种情况下,另一个线程将被安排,而第一个线程可以&#39 ; t取得进展,但否则它通常会运行,直到内核在其分配的时间片结束时抢占它。

当父线程创建子线程时,我不想猜测哪个是更热的&#34;在当前的核心,所以让父母完成其时间片(除非它阻止)是一个合理的默认值。

子线程可能会立即运行,但如果它没有预先占用父线程,那么为什么它应该立即抢占不同内核上的线程也不是很明显。毕竟,它仍然与父线程在同一个进程中,并共享相同的内存,地址映射和其他资源:除非另一个核心完全空闲,否则最好安排child可能与其父级位于同一核心,因为父母在那里的缓存中保留了这些共享资源的可能性很大。

因此,您的线程没有交错的原因可能是 在进程退出之前没有运行一段时间,并且没有任何阻塞I / O或明确的收益率(stdout不会阻止该数据量,因为它可以轻松缓存)。