gpt4 book ai didi

c++ - 多线程应用程序中的设计和技术问题

转载 作者:行者123 更新时间:2023-11-28 03:49:20 25 4
gpt4 key购买 nike

我想讨论与多线程应用程序相关的设计和技术问题/挑战。

我遇到的问题
1.我遇到过多个线程正在使用共享函数/变量导致应用程序崩溃的情况,因此在这种情况下需要适当的保护。
2. 状态机和多线程-

在深入研究多线程应用程序之前,应该记住几点。可能存在与 1. 内存 2. 句柄 3. 套接字等相关的问题。

请在以下几点分享您的经验

  1. 在多线程应用程序中常犯的错误是什么
  2. 任何与多线程相关的具体问题。
  3. 我们应该在线程函数中按值还是按引用传递数据。

最佳答案

嗯,有这么多...

1) 共享函数/过程——它们只是代码,除非代码自行修改,否则不会有问题。局部变量没有问题,因为每个线程都在单独的堆栈上调用(根据定义:)。任何其他数据都可能成为问题并可能需要保护。多任务操作系统上 99.99% 的所有家庭 API 调用都是线程安全的,这也是几乎按照定义。另一位发帖人已经警告过线程本地存储......

2) 状态机。可能有点尴尬。您可以轻松锁定触发 SM 的所有事件,从而确保状态的完整性,但您不能在 SM 锁定时从 SM 内部进行阻塞调用,(这看起来很明显,但我已经这样做了......一次: ).

我有时只从一个线程运行状态机,将事件对象排队到它。这将锁定移动到输入队列,这意味着 SM 更容易调试。这也意味着运行 SM 的线程可以在内部增量队列上实现超时,因此它本身会触发对增量队列上对象的超时调用,(经典示例:具有连接超时的 TCP 服务器套接字 - 数千个套接字对象,每个对象都需要一个独立超时)。

3) '我们应该在线程函数中按值还是按引用传递数据。'。不知道你的意思,在这里。大多数操作系统都允许在创建线程时传递一个指针——随心所欲地使用它。您可以向它传递一个它应该在工作完成时发出信号的事件或一个等待工作请求的队列对象。创建后,您需要某种形式的线程间通信来发送请求和获取结果,(除非您打算使用直接的“读/写/waitForExit”机制 - AV/deadlock/noClose 生成器)。

我通常使用简单的信号量/CS 生产者-消费者队列在工作线程之间发送/接收通信对象,并使用 PostMessage API 将它们发送到 UI 线程。除了队列中的锁定之外,我通常不需要任何更多的锁定。您必须非常努力地尝试使基于消息传递的线程系统死锁,并且线程池之类的东西变得微不足道 - 只需[不。 CPU] 线程并将每个线程传递给相同的队列以等待。

常见错误。许多人请参阅其他海报,我会添加:

a) 直接读取/写入线程字段以传递参数和返回结果,(尤其是在 UI 线程和'worker'线程之间),即'创建线程挂起,将参数加载到线程字段,恢复线程,等待线程退出句柄,从线程字段读取结果,释放线程对象'。这会导致性能因不断创建/终止/销毁线程而受到影响,并且通常会迫使开发人员确保线程在退出应用程序时终止,以防止关闭时出现 AV/216/217 异常。这可能非常棘手,在某些情况下是不可能的,因为一些 API 的阻塞无法解除阻塞。如果开发人员停止这种恶劣的做法,应用关闭问题就会少得多。

b) 尝试以程序方式构建多线程应用程序,例如。尝试等待 UI 事件处理程序中工作线程的结果。构建线程请求对象、使用参数加载它、将其排队到工作线程并退出事件处理程序要安全得多。线程可以获取对象,进行工作,将结果放回对象中,然后(无论如何在 Windows 上)将对象发回 PostMessage。 UI 消息处理程序可以处理结果并处理对象(或回收、重用:)。这种方法意味着,由于 UI 和 worker 总是在不同的数据上操作,这些数据可能比它们都长,所以没有锁定,并且(通常)不需要确保在关闭应用程序时释放工作线程,(这个问题是传奇)。

Rgds,马丁

关于c++ - 多线程应用程序中的设计和技术问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6071071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com