【问题标题】:How to represent thread waiting for a signal on a Sequence Diagram?如何在序列图上表示等待信号的线程?
【发布时间】:2018-07-05 12:38:22
【问题描述】:

一个常见的多线程实现是有一些类,其中Method_A() 在一个线程中运行并被阻塞等待一些信号/事件成员变量(例如WaitForSingleObject)。

在不同线程中运行的交互类然后会调用Method_B(),它会做一些工作,设置信号/事件变量,也许做一些更多的工作,然后返回。

如何在序列图上表示这种交互?

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


编辑:Geert 注意到序列图应该使用 instances, 而不是 classes, 这是一个公平的评论。然而问题是一样的:多条生命线意味着多个实例,但在问题中Method_A()Method_B() 是在 same 实例上运行,只是来自不同的线程。怎么表达?

【问题讨论】:

  • 只要画出来就会很明显。
  • 很遗憾不是@ThomasKilian。几个小时以来,我一直在尝试建立一些合理的模型。同一实例的多个生命线似乎是获得我想要的唯一方法。

标签: uml enterprise-architect sequence-diagram


【解决方案1】:

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

我意识到这可能不是标准的UML,但它似乎以清晰的方式跨越了我想要表达的所有信息,这是最重要的,对吧?

Martin Fowler 在他的书中确实提到过几次,有时非规范图实际上更清晰。所以这是我的借口。 :)

【讨论】:

    【解决方案2】:

    您不应该在序列图中使用类,而应使用将您的类作为分类器的instances/lifelines

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

    这样您就可以为同一个班级添加任意数量的课程。

    【讨论】:

    • 感谢 Geert,但在此示例中,Method_A()Method_B() 都在 相同 实例上运行,但只是来自不同的线程。多条生命线是否意味着多个实例?
    • 是的。如果它在同一个实例上工作,你应该只有一条生命线。还有一些关于激活级别和异步消息的其他选项可能会进一步帮助您。
    【解决方案3】:

    (编辑您可以通过@sim 指出的那样使用异步消息来解决它。这样就可以了。下面的答案显示了幕后发生的事情。所以如果你不这样做不在乎细节,就按照那个答案来吧。)

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

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

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

    然后在不同的线程中调用 Method_B()

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

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

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

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

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

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

    另外:不要在 SD 中使用类。不幸的是,EA 仍然允许这样做(为什么?问他们!)。在他们的文档中隐藏的某个地方有一个句子,您必须使用实例。否则模型会损坏。 SD 始终是(!)彼此对话的示例序列。类不说话,它们只是实例的蓝图。

    【讨论】:

    • 好答案谢谢。我正在记录现有的第三方代码,所以我不能重新设计/重写,但我不认为这是一种特别不寻常的方法。 Method_A 只是被阻止等待调用 Method_B 将设置或提供的东西。
    • 不确定为什么 EA 允许在序列图上使用类。事实上,这是默认行为!但我的 Martin Fowler 书中指出,生命线可以代表任何东西,因此他将它们称为“参与者”而不是对象。
    • EA中隐藏着相当多的龙。 UML 2.5 在 p 上说。 570“在交互图中,生命线描述了流程的时间线,其中时间沿页面向下增加。时间线上的两个事件之间的距离不代表任何字面意义上的时间测量,只有非零时间具有通过了。”和 p。 620 “生命线代表交互中的个人参与者。虽然部件和结构特征的多重性可能大于 1,但生命线仅代表一个交互实体。”。所以“任何事情”肯定是错误的。
    • 如果method_a 处于“阻塞等待”状态,那么它必须执行上述操作之一:要么返回调度程序,要么轮询新消息。两者都是与系统调度程序的交互。
    【解决方案4】:

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

    【讨论】:

    • 谢谢西姆。我还想展示这个对象与其他对象类之间的交互(例如,调用Method_AMethod_B 的对象)。目前,我有一条异步消息标记为信号,来自两条生命线,代表使用该实例的两个线程。这不是标准的,但它可读的。
    猜你喜欢
    • 2013-10-20
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2013-06-02
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多