2009-06-09 49 views
0

这是一个相当直接的问题,我基本上是在寻找一种“最佳实践”方法来实现我想要做的。在线程之间发送字符串数据(Win32)

我有一个Win32 GUI应用程序启动一个工作线程来做一堆阻塞调用。我希望此线程将字符串消息发送回GUI,以便它们可以显示给用户。

目前我在想使用SendMessage会是一个很好的方法,使用WM_COPYDATA?这是正确的轨道?我原本有一个线程安全队列类,它将简单的通知消息发送回GUI线程,然后将该字符串从队列中弹出。不过,我很快退后一步,意识到我不需要排队;我可以直接发送字符串。

任何提示?谢谢!

编辑:为了完整,我使用C++。

+4

您最初的基于队列的“消息传递”方法既标准又优雅。它比使用SendMessage更可能更快更便携。 – 2009-06-09 05:01:48

回答

2

WM_COPYDATA可以正常工作,但我认为最好是简单地定义自己的私人窗口消息。在工作线程上分配字符串,并在完成后将其释放到GUI线程中。使用PostMessage而不是SendMessage,以便不会不必要地阻止您的工作人员。

1

WM_COPYDATA用于在进程之间发送,而不是在一个进程的线程之间发送。您当然可以将它用于线程间通信,但开销可能更大,因为Windows可能需要做更多工作才能将数据复制到临时缓冲区并将其传递到接收应用程序。

如果您关心的是应用程序的简单性 - 坚持更容易实现的方式。如果担心的是性能 - 请执行配置文件并选择更快的变体。

0

在类似情况下,我总是将字符串放在资源文件中,并使用用户消息的参数之一来发送资源标识符。如果您需要发送动态信息,我会创建一个由UI线程分配的线程安全缓冲区,并将指向缓冲区的指针传递给工作线程。

2

正如其他几个人指出,自定义窗口消息可能是最好的办法。

要考虑的另一件事是正在使用的实际内存。通过在线程之间传递字符串,我猜你还要传递线程之间字符串的所有权。这可能会导致你应该知道,包括

  • 内存泄漏的几个问题:如果线程A职位的消息,会发生什么,因此赠送所有权,但该窗口被销毁前线程B处理的消息
  • 灿内存管理器支持你的字符串安全地分配和释放内存在不同的线程上。

第一个问题可能是最有可能影响您的应用程序的问题。我认为这是重新考虑你的原始方法的一个很好的理由。只要队列本身得到适当的管理,就可以消除内存泄漏,因为队列可以充当内存的临时所有者。

0

很大程度上取决于您希望信息流动的方式。

共享信息的最快方式可能是使用某种形式的标记来防止竞争条件的共享变量。如果有多个字符串,你可以有一个排队的队列。

但是,如果您没有数据同步的经验,那么该模型可能很难得到正确。发送带有附加数据的自定义Windows消息可能会证明是一个更简单的(少bug)模型。

1

使用异步代理库,Visual Studio 2010使这些场景变得更加容易。你可以看看在文档here的演练,但这里的一些不那么伪代码:

//somewhere stateful, e.g. main 
unbounded_buffer<stringtype> buff; 

//thread 1 
{ 
    //send a message asynchronously to the buffer 
    asend(&buff,stringtype("hello world"); 
} 

//thread 2 
{ 
    //get the message out of the buffer 
    //if this is a UI thread, receive is blocking so use try_receive which isn't 
    stringtype message = receive(&buff) 
} 

如果我今天的工具集,这样做,我会使用一个线程队列。