0

我正在开发一个 DirectShow 应用程序。我遇到了一个死锁问题,这个问题似乎是由线程调用的回调函数中的获取锁引起的。这是我在 MSDN 论坛中提出的问题:

http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/f9430f17-6274-45fc-abd1-11ef14ef4c6a

现在我必须避免在该线程中获取锁。但问题是,我必须将音频输出到另一个线程,我怎样才能将数据不加锁地放到另一个线程?

有人告诉我,我可以使用 win32 sdk 的 PostMessage 将数据发布到另一个线程。但是,为了得到消息,我必须运行一个 Windows 程序。我的程序是一个 Python C++ 扩展模块。添加循环来拉取消息可能非常困难。所以我认为另一种在线程之间传递数据而不锁定的方法。(其实……生产者线程不能被锁定,但是消费者线程可以做到。)

锁还是不锁,这是个问题。

那么问题来了怎么办?

谢谢。

- - - 编辑 - - -

我想我知道为什么会出现死锁,那可能不是 DirectShow 的问题。

主线程是Python自己的,调用stop,即持有GIL。并在线程返回中停止等待 DirectShow 的回调。但是回调获取 GIL。

看起来像这样

Main(Hold GIL) -> Stop(Wait callback) -> Callback(Wait GIL) -> GIL(Hold by Main thread)

该死的!这就是为什么我不太喜欢多线程的原因。不管怎样,谢谢你的帮助。

4

2 回答 2

1

如果您在纯 Python 中执行此操作,我会使用一个Queue对象;这些缓冲写入但在读取时阻塞的数据,直到有东西可用,并在引擎盖下进行任何必要的锁定。

这是一种极其常见的数据类型,无论您当前使用何种语言或工具链,都应该始终提供一些等效的数据类型;例如,C++ 中有一个可用的 STL 队列,但标准没有指定线程安全特性(请参阅本地实现文档)。

于 2009-02-09T17:56:52.950 回答
0

好吧,如果您的两个线程都可以处理相同数据的重复副本,理论上可以避免锁定。在 MSDN 论坛中阅读您的问题后...

“所以为了避免死锁,我不应该在抓取回调函数中获取任何锁?如果我想将音频输出到另一个线程怎么办?”

我认为您应该能够将音频数据存放在出列队列(STL 类)中,然后从另一个线程中获取这些数据。然后,这个其他线程可以处理您的音频数据。

我很高兴您的问题已经解决,因为我询问您的操作系统的原因是您提到的文档说您不应该因为 win16Mutexes 的一些问题而等待其他线程。Windows XP 上没有 win16mutexes(程序在 ntvdm/wow16 上运行时除外),因此您应该能够使用锁来同步这些线程。

于 2009-02-09T17:58:42.977 回答