what's the most common method to translate UML signals and their receivers into C ? What would be the C equivalent of a signal and its receiver?
Is it just a method call at the end of the day?
CodePudding user response:
From the Rational UML documentation:
https://www.ibm.com/docs/en/rational-soft-arch/9.7.0?topic=diagrams-signals
In UML models, signals are model elements that are independent of the classifiers that handle them. Signals specify one-way, asynchronous communications between active objects. Signals are often used in event-driven systems and distributed computing environments. For example, a communications system might contain a Pager class, whose objects wait for, and respond to, Page signals. Signals differ from other message types in that when an object receives a signal, the object does not need to return anything, but reacts to the receipt of a signal according to the behavior specified by its receptions.
All signals are assumed to have a send( ) operation. A signal’s attributes represent the data it carries in its send operation. Signals can have no other operations.
In other words, UML "signals" (and "receivers", "events", etc.) are abstractions that map to your APPLICATION and, in turn. The are NOT "language constructs" per se.
More specifically, when you app implements a "signal", it might have a C function or class method called "send()". Send() might send a Posix signal (e.g. kill()), it might post something to a message queue or any of a million other different possibilities.
In short, if your "design" specifies UML "signals", then your C code will depend entirely on whatever "implementation" you've chosen.
In that sense, yes: it IS "just a method call at the end of the day" :)
CodePudding user response:
Though the answer of paulsm4 is already correct I would like to add what the UML authors say about signals. On pp. 167 of UML 2.5 you find:
10.3.3.1 Signals
A Signal is a specification of a kind of communication between objects in which a reaction is asynchronously triggered in the receiver without a reply. The receiving object handles Signals as specified by clause 13.3. The data carried by the communication are represented as attributes of the Signal. A Signal is defined independently of the Classifiers handling it.
The sender of a Signal will not block waiting for a reply but continue execution immediately. By declaring a Reception associated to a given Signal, a Classifier specifies that its instances will be able to receive that Signal, or a subtype thereof, and will respond to it with the designated Behavior.
A Signal may be parameterized, bound, and used as TemplateParameters.
10.3.3.2 Receptions
A Reception specifies that its owning Class or Interface is prepared to react to the receipt of a Signal. A Reception matches a Signal if the received Signal is a specialization of the Reception’s signal. The details of how the object responds to the received Signal depend on the kind of Behavior associated with the Reception and its owning Class or Interface. See 13.2. The name of the Reception is the same as the name of the Signal. A Reception may only have in Parameters (see 9.4.3) that match the attributes of the Signal by name, type, and multiplicity.
Since UML per se is language-agnostic that's all you have. And how any compiler/coder realizes this is completely open.
CodePudding user response:
To the two already excellent answer's, I'd like to add some practical aspects:
Who best than Booch, Rumbaugh and Jacobson, the inventors of UML (and the creators of early Rational tools) could explain what a signal is supposed to be:
A message is a named object that is sent asynchronously by one object and then received by another. A signal is a classifier for messages; it is a message type. (...) Signals have a lot in common with plain classes. (...) The attributes of a signal serve as its parameters.
- Booch, Rumbaugh and Jacobson in UML User Guide, 2nd ed. (Chap 21, Events and signals)
In C signals would therefore often be represented by classes. A reception would then be represented by a member function with an argument of that class.
A frequent alternative is to represented them with a member function: its parameters are the signal parameters (example here). That function should be designed to be called asynchronously. This is often sufficient, but it'd make specialization of signals more tricky and difficult to maintain.
Some additional remarks:
Most classes are not active classes: Since they do not own their process nor their thread, OS level signals are rarely the relevant implementation or receptions. When they are, usually some callback function maps them to the chosen implementation.
Separation of concerns and single responsibility principle made their way through: In the case of a class-based implementation a signal's responsibility would be the message content and not in addition to dispatch itself (Change in the dispatching technology would be another reason to change that infringes SRP).
So the sender would either invoke a sending function of a dispatching class (event queue, which could be as simple as an observer variant or a chain of responsibility), or invoke the "reception" function of the receiver directly (if needed using some asynchronous mechanism like
std::future
to use async calls or promises).