如何在序列图上表示线程等待信号?

时间:2018-07-05 12:38:22

标签: uml enterprise-architect sequence-diagram

常见的多线程实现是使用某个类,其中Method_A()在线程中运行,并且处于阻塞状态,等待某些信号/事件成员变量(例如WaitForSingleObject)。

在不同线程中运行的交互类将随后调用Method_B(),它可以完成一些工作,设置信号/事件变量,也许还要执行更多工作,然后返回。

我如何在序列图上表示这种相互作用?

我是否应该有两条生命线,即使每个线程都在类的同一实例上运行,每个线程也要一条生命线?我的建模工具(Enterprise Architect 12)不允许同一个类在序列图上出现两次,因此不鼓励这样做。


编辑:Geert指出,序列图应使用实例,而不是,这是一个合理的注释。但是问题是相同的:多个生命线将意味着多个实例,但是问题Method_A()Method_B() same 实例上运行,只是来自不同的线程。怎么表示呢?

4 个答案:

答案 0 :(得分:2)

编辑您可以通过使用@sim指出的异步消息来解决此问题。这样做就可以了。下面的答案显示了幕后发生的事情。不在乎细节,请给出答案。)

您要问的是更多的设计,而不是UML问题。即,并发实例如何相互通信。你先说

  

Method_A()正在线程中运行,并且处于阻塞等待状态

仅仅意味着它由于被阻止而不能接受任何东西。现在,从您的问题的上下文中猜测,我假设您仍然要与该实例进行通信,因为

  

然后在其他线程中调用Method_B()

因此,为了能够接受消息,实例必须处于适当的状态。有两种方法可以实现这一目标。一个简单的方法是,如果相应的操作系统对此提供支持,则返回调度程序并告诉他它正在等待某些消息。

enter image description here

现在,当调用method_b时,您会在Object1内知道自己在method_a内处于某种空闲状态,并执行适当的(返回)操作。

另一种方法是轮询调度程序以获取传入消息并处理它们。

您需要记住,发送消息通常不会直接处理实例,而是会告诉系统调度程序与适当的实例进行交互(至少在大多数OS中如此)。

我只是从Modula2编译器中记得我曾经写过它具有协程的概念,该协程允许并发线程在已编译的代码中运行。但是基本上,这只是映射到在一个半单线程的引擎盖下运行的两个独立线程,并且在进行详细介绍时会用两条生命线来描述它。

N.B .:它应该是操作而不是方法(因为它是由消息调用的;而方法是在操作内部实现的)。并且按照惯例,它们应该以小写字符开头。

还有:不要在SD中使用类。不幸的是,EA仍然允许这样做(为什么?问他们!)。在他们的文档中某个地方隐藏着一个句子,您必须使用实例。否则,模型将崩溃。 SD始终是(!)互相交谈的实例序列的样本。类不会说话,它们只是实例的蓝图。

答案 1 :(得分:1)

永远不要在序列图中使用类,而应使用将类作为分类器的实例/生命线

如果在将类拖到序列图时按住控件,则可以选择将其作为实例而不是作为类。

通过这种方式,您可以为同一个班级添加任意数量的

答案 2 :(得分:1)

您要查找的符号是异步消息。从理论上讲,您可以使用一条生命线来表达这一点。但这是不可读的。因此,可能在您的类中有一个线程类的两个实例,并显示这些实例之间的交互。但是永远不要在序列图中显示类。 但是,为什么要使用序列图呢?对于这种内部行为,活动图最可能更合适。在那里,您可以使用发送和接收消息元素来表达每个线程的行为。或者,如果将其显示在一个图中,则可以使用fork。

答案 3 :(得分:1)

我决定采用的方法是为同一实例添加两条生命线,然后使用<<thread>>构造型标记一条生命线,并将其运行的线程添加到名称中:

My attempt at multi-threaded Sequence Diagram

我意识到这可能是不是标准的UML,但是它似乎可以理解我想清楚表达的所有信息,这是最重要的,对吧?

马丁·福勒(Martin Fowler)确实在书中提到过几次,有时非规范性的图表实际上更为清晰。这就是我的借口。 :)