调试是否会改变多线程C++;节目? 我正在研究一个多线程的C++程序,它处理很多同步问题。我正在使用VisualStudio2008

调试是否会改变多线程C++;节目? 我正在研究一个多线程的C++程序,它处理很多同步问题。我正在使用VisualStudio2008,c++,multithreading,debugging,visual-studio-2008,asynchronous,C++,Multithreading,Debugging,Visual Studio 2008,Asynchronous,当我使用断点调试程序时,程序的运行时行为(语句跨线程执行的顺序)似乎发生了变化。这可以解释吗?这里的概念是什么?我希望执行的顺序保持不变 第二个问题-如果Thread1被等待函数调用阻塞。Thread2具有等待执行的语句,处于就绪状态。是否存在程序将等待Thread1继续而不是将执行交给Thread2的情况?我已经删除了两个线程之间的所有依赖关系,并确保Thread2不等待任何资源 感谢您的回复。对该主题做了一些很好的总结: 在调试器下运行时,可能不会出现多线程错误。多线程错误对应用程序中的事件

当我使用断点调试程序时,程序的运行时行为(语句跨线程执行的顺序)似乎发生了变化。这可以解释吗?这里的概念是什么?我希望执行的顺序保持不变

第二个问题-如果Thread1被等待函数调用阻塞。Thread2具有等待执行的语句,处于就绪状态。是否存在程序将等待Thread1继续而不是将执行交给Thread2的情况?我已经删除了两个线程之间的所有依赖关系,并确保Thread2不等待任何资源

感谢您的回复。

对该主题做了一些很好的总结:

在调试器下运行时,可能不会出现多线程错误。多线程错误对应用程序中的事件计时非常敏感。在调试器下运行应用程序会更改计时,因此可能会掩盖问题。当您的应用程序在客户环境的测试或更糟的测试中失败,但在调试器下可靠地运行时,几乎可以肯定这是代码中的时间问题


…对于后一个问题,更重要的是要理解,在大多数情况下,操作系统可以随时随意中断任何线程的执行,即使是“准备好”执行的线程。

记住:在调试多线程应用程序时,通常无法调试它“直到它起作用”

你需要有一种方法来向自己证明不会出现死锁,并且所有的数据访问都在需要的地方被序列化。这很难做到,甚至有经验的开发人员也可能错过某些情况

因此,设计多线程应用程序以保证某些属性(例如,无死锁)非常重要。请注意,前一句中没有提到调试。它需要按设计工作,而不是按错误查找工作

有两个核心问题:

  • 对数据结构访问的序列化

  • 僵局

  • 我在下面讨论的事件驱动或CSP方法自动解决了#1.死锁问题并非无关紧要,仍然是一个活跃的研究课题。也就是说,证明没有死锁的方法(以及设计死锁的方法!)

    设计的一个例子是,可以更容易地检查和正式证明某些属性,如无死锁

    CSP方法在大多数应用程序开发框架中都可用,可以作为无共享事件驱动系统来实现。核心功能包括:

    • 线程通过在彼此之间发送事件(消息)进行通信

    • 数据结构从不在线程之间直接共享,而是由事件拥有数据

    • 唯一的同步是在发布事件时按顺序访问事件队列

    只要高层抽象不使用事件传递来重新实现易于死锁的抽象,这本身就可以确保不会出现死锁。例如,即使使用事件传递也可以获得问题中的死锁,但是现在您通过事件(消息)显式传递有关资源的信息因此,这个问题至少是明确的,你不得不考虑。可以说,这个问题并没有被掩盖起来


    证明不会发生死锁/活锁的方法可以更容易地应用于实现CSP的事件传递生产代码。事件接受代码可以提供运行时自省,允许提取每个状态的接受事件集,以及状态集(内部为状态机)。这些信息通常足以证明不存在死锁的可能性,或者可以列举一小部分死锁场景,然后以其他方式进行处理。毕竟,CSP形式主义通常无法捕获软件的完整语义,因此语义本身可能被用来进一步表明死锁不会发生,或者这是另一种处理方式。

    当然。即使你什么都不改变,多线程程序的行为也会改变——更不用说调试器了。只是不要对线程和线程之间执行语句的顺序做任何假设。如果没有适当的同步,迟早会发生所有不同的排列调试代码时也不会使用优化。您无法预测两个线程的执行顺序,它们可能(或将)执行在同一程序的两个不同运行之间执行不同顺序的语句,而不改变任何程序。甚至切换编译器选项也可以改变行为,因为它也可以改变时间。考虑添加大量日志记录。(但随着时间的变化,这也可能会导致查找错误的问题——但良好的日志记录总是值得的)。