Events: Difference between revisions

21,011 bytes added ,  5 months ago
added Easylang
(Add LFE version of events based on the Erlang version)
(added Easylang)
 
(32 intermediate revisions by 19 users not shown)
Line 28:
 
The event interface:
<langsyntaxhighlight lang="ada">protected type Event is
procedure Signal;
procedure Reset;
Line 34:
private
Fired : Boolean := False;
end Event;</langsyntaxhighlight>
The event implementation:
<langsyntaxhighlight lang="ada">protected body Event is
procedure Signal is
begin
Line 49:
null;
end Wait;
end Event;</langsyntaxhighlight>
With the event defined above:
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Test_Events is
Line 68:
Put_Line ("Signal X");
X.Signal;
end Test_Events;</langsyntaxhighlight>
Sample output:
<pre>
Line 77:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">SetTimer, internal, 1000
Return
 
Line 87:
F2:: ; external event: fire on F2 key press
TrayTip, external, f2 key pressed
Return</langsyntaxhighlight>
 
 
=={{header|BASIC256}}==
{{trans|Gambas}}
<syntaxhighlight lang="basic256">
subroutine Timer1_Timer()
print hour; ":"; minute; ":"; second
end subroutine
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Gambas.
</pre>
 
 
=={{header|BBC BASIC}}==
Line 93 ⟶ 107:
===API===
This uses a Windows event object:
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB"
WAIT_TIMEOUT = 258
Line 109 ⟶ 123:
DEF PROCelapsed
SYS "SetEvent", hEvent%
ENDPROC</langsyntaxhighlight>
===Native===
This uses a simple variable as a semaphore:
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB"
Event% = FALSE
Line 127 ⟶ 141:
DEF PROCelapsed
Event% = TRUE
ENDPROC</langsyntaxhighlight>
 
=={{header|C}}==
Using pipe to communicate to <code>fork</code>ed child. Since child will be blocking trying to read the other end of the pipe, this can be used for synchronization.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <unistd.h>
 
Line 149 ⟶ 163:
}
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Timers;
 
Line 171 ⟶ 185:
((Timer)sender).Stop();
}
}</langsyntaxhighlight>
Sample output:
<pre>10-11-2010 18:35:11
10-11-2010 18:35:12</pre>
 
=={{header|Clojure}}==
{{trans|Go}}
<syntaxhighlight lang="lisp">(ns async-example.core
(:require [clojure.core.async :refer [>! <! >!! <!! go chan]])
(:require [clj-time.core :as time])
(:require [clj-time.format :as time-format])
(:gen-class))
 
;; Helper functions (logging & time stamp)
; Time stamp format
(def custom-formatter (time-format/formatter "yyyy:MM:dd:ss.SS"))
 
(defn safe-println [& more]
" This function avoids interleaving of text output when using println due to race condition for multi-processes printing
as discussed http://yellerapp.com/posts/2014-12-11-14-race-condition-in-clojure-println.html "
(.write *out* (str (clojure.string/join " " more) "\n")))
 
(defn log [s]
" Outputs mesage with time stamp "
(safe-println (time-format/unparse custom-formatter (time/now)) ":" s))
 
;; Main code
(defn -main [& args]
(let [c (chan)]
(log "Program start")
(go
(log "Task start")
(log (str "Event received by task: "(<! c))))
 
(<!!
(go
(log "program sleeping")
(Thread/sleep 1000) ; Wait 1 second
(log "Program signaling event")
(>! c "reset") ; Send message to task
))))
 
; Invoke -main function
(-main)
</syntaxhighlight>
{{Output}}
<pre>
2016:10:18:06.93 : Program start
2016:10:18:06.94 : task start
2016:10:18:06.94 : program sleeping
2016:10:18:07.94 : Program signaling event
2016:10:18:07.94 : Event received by task: reset
</pre>
 
=={{header|Delphi}}==
<langsyntaxhighlight Delphilang="delphi">program Events;
 
{$APPTYPE CONSOLE}
Line 230 ⟶ 293:
end;
Readln;
end.</langsyntaxhighlight>
Sample output:
<pre>
Line 238 ⟶ 301:
 
=={{header|E}}==
<langsyntaxhighlight lang="e">def makeEvent() {
def [var fired, var firer] := Ref.promise()
Line 261 ⟶ 324:
return event
}</langsyntaxhighlight>
The event object has this behavior: the return value of <code>.wait()</code> will be resolved after the time of the earliest <code>.signal()</code> for which there is no intervening <code>.reset()</code>.
<langsyntaxhighlight lang="e">def e := makeEvent()
 
{
Line 278 ⟶ 341:
})
println("[1] Waiting 1 second...")
}</langsyntaxhighlight>
 
=={{header|EasyLang}}==
 
[https://easylang.dev/show/#cod=y89TKMnMTS3iUlBQyM0vS1UoSsxLyc9NU9BSMDQwQOWB1CRnFiXnpCoYgdhgjQqGXHpc+XlAzaXFqfEp+eV5cKMgQhVQuhJFux4XRLcBFwA= Run it]
 
<syntaxhighlight>
on timer
move randomf * 100 randomf * 100
circle 2
timer 1
.
on mouse_down
move mouse_x mouse_y
circle 2
.
timer 0
</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="elixir">defmodule Events do
def log(msg) do
time = Time.utc_now |> to_string |> String.slice(0..7)
IO.puts "#{time} => #{msg}"
end
def task do
log("Task start")
receive do
:go -> :ok
end
log("Task resumed")
end
def main do
log("Program start")
{pid,ref} = spawn_monitor(__MODULE__,:task,[])
log("Program sleeping")
Process.sleep(1000)
log("Program signalling event")
send(pid, :go)
receive do
{:DOWN,^ref,_,_,_} -> :task_is_down
end
end
end
 
Events.main</syntaxhighlight>
 
{{out}}
<pre>
06:27:05 => Program start
06:27:05 => Program sleeping
06:27:05 => Task start
06:27:06 => Program signalling event
06:27:06 => Task resumed
</pre>
 
=={{header|Erlang}}==
Events can be implemented by using the selective receive expression and erlang's built in message passing. Here task waits for the message 'go' before it will continue.
<langsyntaxhighlight lang="erlang">
-module(events).
-compile(export_all).
Line 305 ⟶ 425:
P ! go,
timer:sleep(100).
</syntaxhighlight>
</lang>
'''Output:'''
<langsyntaxhighlight lang="erlang">
66> events:main().
0: 0:57 => Program start
Line 315 ⟶ 435:
0: 0:58 => Task resumed
ok
</syntaxhighlight>
</lang>
 
=={{header|F_Sharp|F#}}==
{{trans|C#}}
<langsyntaxhighlight lang="fsharp">open System
open System.Timers
 
Line 333 ⟶ 453:
timer.Start()
ignore <| Console.ReadLine()
0</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
{{trans|Gambas}}
<syntaxhighlight lang="freebasic">
Sub Timer1_Timer()
Print Time
End Sub
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Gambas.
</pre>
 
 
=={{header|FutureBasic}}==
Event timer fires every tenth of a second
<syntaxhighlight lang="futurebasic">
timerbegin, 0.1, YES
cls : printf @"%@", time(@"h:mm:ss a zzz")
timerend
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
4:44:36 PM EDT
</pre>
 
=={{header|Gambas}}==
<syntaxhighlight lang="gambas">Public Sub Timer1_Timer()
 
Print Str(Time(Now))
 
End</syntaxhighlight>
Output:
<pre>
16:14:18
16:14:19
16:14:20
16:14:21
16:14:22
16:14:23
16:14:24
16:14:25
</pre>
 
=={{header|Go}}==
A Go channel can represent an manual-reset event, as described by the task. The two states of signaled and reset correspond to the presence or absence of a value on the channel. The program signals by sending a value on the channel. The event is reset when the waiting task explicitly executes the channel receive operation, <-event.
<langsyntaxhighlight lang="go">package main
 
import (
Line 359 ⟶ 525:
event <- 0
time.Sleep(100 * time.Millisecond)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 370 ⟶ 536:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Concurrent (threadDelay, forkIO)
import Control.Concurrent.SampleVar
 
Line 380 ⟶ 546:
signalEvent (Event sv) = writeSampleVar sv ()
resetEvent (Event sv) = emptySampleVar sv
waitEvent (Event sv) = readSampleVar sv</langsyntaxhighlight>
<langsyntaxhighlight lang="haskell">main = do e <- newEvent
forkIO (waitTask e)
putStrLn "[1] Waiting 1 second..."
Line 391 ⟶ 557:
waitTask e = do putStrLn "[2] Waiting for event..."
waitEvent e
putStrLn "[2] Received event."</langsyntaxhighlight>
Note: Because there is no serialization of the text output, there is a chance that it will appear interleaved.
 
Line 398 ⟶ 564:
The following only works in Unicon. The example illustrates the multiple tasks can
receive the same event:
<langsyntaxhighlight lang="unicon">record Event(cond, value)
 
procedure main()
Line 417 ⟶ 583:
signal(event.cond,0)
every wait(t1|t2)
end</langsyntaxhighlight>
 
Sample run:
Line 428 ⟶ 594:
Task one received event.
->
</pre>
 
=={{header|JavaScript}}==
An example using the [[wp:Yahoo!_UI_Library|YUI]] library:
<syntaxhighlight lang="javascript">YUI().use('event-custom', function(Y) {
// add a custom event:
Y.on('my:event', function () {
alert("Event fired");
});
// fire the event after one second:
setTimeout(function () {
Y.fire('my:event');
}, 1000);
});</syntaxhighlight>
An example simulating [[wp:Document_Object_Model|DOM]] events:
<syntaxhighlight lang="javascript">YUI().use('node-event-simulate', function(Y) {
// add a click event handler to a DOM node with id "button":
Y.one("#button").on("click", function (e) {
alert("Button clicked");
});
// simulate the click after one second:
setTimeout(function () {
Y.one("#button").simulate("click");
}, 1000);
});</syntaxhighlight>
 
=={{header|Julia}}==
Julia provides a variety of high and low level functions and macros for multitasking and events.
The code below uses a Condition() event semaphore created in the base thread for communication
between two child threads.
 
<syntaxhighlight lang="julia">
function dolongcomputation(cond)
det(rand(4000, 4000))
Base.notify(cond)
end
 
function printnotice(cond)
Base.wait(cond)
println("They are finished.")
end
 
function delegate()
println("Starting task, sleeping...")
condition = Base.Condition()
Base.@async(printnotice(condition))
Base.@async(dolongcomputation(condition))
end
 
delegate()
sleep(5)
println("Done sleeping.")
</syntaxhighlight>
{{output}}<pre>
Starting task, sleeping...
They are finished.
Done sleeping.
</pre>
 
=={{header|LFE}}==
<lang lisp>
;;;
;;; This is a straight port from the Erlang version.
;;;
;;; You can run this in the LFE REPL by slurping the file:
;;;
;;; > (slurp "events.lfe")
;;; > (main)
;;;
(defmodule events
(export all))
 
{{trans|Erlang}}
 
Paste in the REPL:
 
<syntaxhighlight lang="lisp">
(defun log (msg)
(let ((`#(tuple ,h ,m ,s) (erlang:time)))
(lfe_io:format "~2.B:~2.B:~2.B => ~s~n" `(list ,h ,m ,s ,msg))))
 
(defun task ()
Line 453 ⟶ 670:
(log "Task resumed"))
 
(defun mainrun ()
(log "Program start")
(let ((pid (spawn (lambda () (task)))))
Line 462 ⟶ 679:
(! pid 'go)
(timer:sleep 100))))
</syntaxhighlight>
</lang>
 
Usage:
However, OTP comes with a gen_event behavior that is more robust and resilient than this version.
 
<pre>
=={{header|JavaScript}}==
> (run)
An example using the [[wp:Yahoo!_UI_Library|YUI]] library:
18:34:53 => Program start
<lang javascript>YUI().use('event-custom', function(Y) {
18:34:53 => Program sleeping
// add a custom event:
18:34:53 => Task start
Y.on('my:event', function () {
18:34:54 => Program signalling event
alert("Event fired");
18:34:54 => Task resumed
});
ok
// fire the event after one second:
</pre>
setTimeout(function () {
OTP comes with a <code>gen_even</code>t behavior that is more robust and resilient than this version. That is what should be used for any non-toy example or project.
Y.fire('my:event');
 
}, 1000);
=={{header|Lingo}}==
});</lang>
Lingo/Director uses (stateless) events for system/application state change notifications, user action notifications and inter-sprite communication.
An example simulating [[wp:Document_Object_Model|DOM]] events:
 
<lang javascript>YUI().use('node-event-simulate', function(Y) {
To catch an event, a corresponding event handler - a function with a predefined name - has to be definined in the code. Examples for such event handlers are:
// add a click event handler to a DOM node with id "button":
<syntaxhighlight lang="lingo">-- the current window was closed
Y.one("#button").on("click", function (e) {
on closeWindow
alert("Button clicked");
...
});
end
// simulate the click after one second:
setTimeout(function () {
Y.one("#button").simulate("click");
}, 1000);
});</lang>
 
-- the left mouse button was pressed by the user
=={{header|Mathematica}}==
on mouseDown
...
end</syntaxhighlight>
Also "Sprites" (visual elements) receive events by setting up such event handlers in scripts attached to them. Both predefined and custom events can be sent programmatically to sprites, e.g. using:
<syntaxhighlight lang="lingo">-- send event #mouseDown programmatically to sprite 1
sendSprite(1, #mouseDown)
 
-- send custom event #foo to named sprite "bar"
sendSprite("bar", #foo)
 
-- send custom event #fooBar to all existing sprites
sendAllSprites(#fooBar)</syntaxhighlight>
 
Using a binary plugin ("Xtra"), in Windows also lower level window messages can be both sent and received:
{{libheader|Msg Xtra}}
<syntaxhighlight lang="lingo">mx = xtra("Msg").new()
 
-- send message WM_LBUTTONDOWN to a specific window identified by HWND hwnd
WM_LBUTTONDOWN = 513
MK_LBUTTON = 1
lParam = 65536*y + x
mx.send_msg (hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lParam)
 
-- listen for WM_COPYDATA and WM_MOUSEWHEEL messages sent to current application
-- window, notify Lingo callback function 'msgReceived' when such messages occur.
-- This callback function will receive hwnd, message, wParam and lParam as arguments
-- (and for WM_COPYDATA messages also the data that was sent as ByteArray).
WM_COPYDATA = 74
WM_MOUSEWHEEL = 522
mx.msg_listen([WM_COPYDATA, WM_MOUSEWHEEL], VOID, #msgReceived)</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Mathematica supports events from timers (via Pause[]), task schedule descriptors. This will print a message after 4 seconds, then terminate the program.
<langsyntaxhighlight Mathematicalang="mathematica">Print["Will exit in 4 seconds"]; Pause[4]; Quit[]
->Will exit in 4 seconds</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight lang="nim">import posix
 
var p: array[2, cint]
Line 506 ⟶ 751:
discard p[1].write(addr p[0], 1)
var x: cint = 0
discard wait (addr x)
else:
discard close p[1]
discard p[0].read(addr p[1], 1)
echo "received signal from pipe"</langsyntaxhighlight>
 
===Stdlib Semaphore===
This version using locks module for signaling the condition.
 
<syntaxhighlight lang="nim">import locks
from os import sleep
import times
from strformat import fmt
 
var
# condition variable which shared across threads
cond: Cond
lock: Lock
threadproc: Thread[void]
 
proc waiting {.thread.} =
echo "spawned waiting proc"
let start = getTime()
cond.wait lock
echo fmt"thread ended after waiting {getTime() - start}."
 
proc main =
initCond cond
initLock lock
threadproc.createThread waiting
echo "in main proc"
os.sleep 1000
echo "send signal/event notification"
signal cond
joinThread threadproc
deinitCond cond
deinitLock lock
 
main()</syntaxhighlight>
 
Compile and run: <pre>nim c -r --threads:on events_cond.nim</pre>
{{out}}
<pre>in main proc
spawned waiting proc
send signal/event notification
thread ended after waiting 1 second, 61 microseconds, and 311 nanoseconds.</pre>
 
=={{header|Oforth}}==
Line 517 ⟶ 802:
An event is often implemented with a control channel. A task is waiting for an object on the channel. When the event occurs, another task sends an object on this channel.
 
<langsyntaxhighlight Oforthlang="oforth">func: anEvent
{
| ch |
Channel new ->ch
#[ ch receive "Ok, event is signaled !" println ] &
System sleep(1000)
ch send($myEvent) ;</syntaxhighlight>
}</lang>
 
An emitter is a general implementation for handling events : an emitter waits for events emitted and launches listeners that are waiting for those events.
<syntaxhighlight lang="oforth">import: emitter
<lang Oforth>func: anEvent2
 
{
: anEvent2
| e i |
Emitter new(null) ->e
e onEvent($myEvent, #[ "Ok, eventEvent is signaled !" println ])
10 loop: i [ System sleep(1000) e emit($myEvent) ]
1000 System sleep
e close
$myEvent e emit
}</lang>
]
e close ;</syntaxhighlight>
 
=={{header|Oz}}==
{{trans|Haskell}}
Events can be implemented as mutable references to dataflow variables:
<langsyntaxhighlight lang="oz">declare
fun {NewEvent}
{NewCell _}
Line 567 ⟶ 853:
{Delay 1000}
{System.showInfo "[1] Signaling event."}
{SignalEvent E}</langsyntaxhighlight>
However, this code is quite unidiomatic. If we need to wait for an event just once (like in this example), we can simply use a dataflow variable, i.e. an event that cannot be reset:
<langsyntaxhighlight lang="oz">declare
E
in
Line 581 ⟶ 867:
{Delay 1000}
{System.showInfo "[1] Signaling event."}
E = unit</langsyntaxhighlight>
If we want to synchronize two threads repeatedly and exchange data, it is natural to use ports and streams. Streams are just lists with an unbound tail. A port is basically a pointer to the tail of a list, i.e. it keeps track of where the next event can be written to:
<langsyntaxhighlight lang="oz">declare
MyPort
in
Line 602 ⟶ 888:
{System.showInfo "[1] Signaling event."}
{Port.send MyPort unit}
end</langsyntaxhighlight>
It is important to limit the scope of a stream as much as possible to ensure that the already read part of the stream is garbage-collected.
 
Line 608 ⟶ 894:
This is an example of using the [http://search.cpan.org/perldoc?AnyEvent AnyEvent] module.
The result is this: it prints "Hello world!" after one second, then after another second prints "Hi!" four times every quarter of a second and then immediately prints "Bye!" and quits:
<langsyntaxhighlight Perllang="perl">use AnyEvent;
 
# a new condition with a callback:
Line 638 ⟶ 924:
 
# wait for the $quit condition to be ready:
$quit->recv();</langsyntaxhighlight>
This is the same using AnyEvent [http://search.cpan.org/perldoc?AE simplified API]:
<langsyntaxhighlight Perllang="perl">use AnyEvent;
 
my $quit = AE::cv sub { warn "Bye!\n" };
Line 654 ⟶ 940:
};
 
$quit->recv;</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
The primary synchronisation primitive in phix is the critical section, in the following the leave_cs()
{{trans|Go}}
in main() acts as signalling an event, and the one in echo() from whichever goes first acts to signal
<lang perl6>note now, " program start";
that the other can/should resume.
my $event = Channel.new;
<!--<syntaxhighlight lang="phix">(notonline)-->
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">lock</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">init_cs</span><span style="color: #0000FF;">()</span>
my $todo = start {
<span style="color: #008080;">include</span> <span style="color: #000000;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
note now, " task start";
$event.receive;
<span style="color: #008080;">procedure</span> <span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
note now, " event reset by task";
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">format_timedate</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">date</span><span style="color: #0000FF;">(),</span><span style="color: #008000;">" h:m:s\n"</span><span style="color: #0000FF;">))</span>
}
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
note now, " program sleeping";
<span style="color: #008080;">procedure</span> <span style="color: #000000;">echo</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
sleep 1;
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- see note</span>
note now, " program signaling event";
<span style="color: #7060A8;">enter_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
$event.send(0);
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
await $todo;</lang>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">enter_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">threads</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">create_thread</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"echo"</span><span style="color: #0000FF;">),{</span><span style="color: #008000;">"job1"</span><span style="color: #0000FF;">}),</span>
<span style="color: #000000;">create_thread</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"echo"</span><span style="color: #0000FF;">),{</span><span style="color: #008000;">"job2"</span><span style="color: #0000FF;">})}</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"main"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"free"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">wait_thread</span><span style="color: #0000FF;">(</span><span style="color: #000000;">threads</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"done\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
Typically the first thread to attempt enter_cs() is released first, but there is
<pre>Instant:1403880984.089974 program start
no guarantee of that. The sleep(rnd()/10) above evens out the likelihood, by
Instant:1403880984.095400 program sleeping
pausing for up to 0.1s, but otherwise isn't necessary.
Instant:1403880984.095491 task start
<pre>
Instant:1403880985.099381 program signaling event
main 10:00:57
Instant:1403880985.109395 event reset by task</pre>
free 10:00:58
 
job2 10:00:59
See also [[Handle_a_signal#Perl_6]] for an example of using Supplies to do reactive programming based on events (Unix signals in this case).
job1 10:01:00
done
</pre>
External events such as timers and user input are handled in pGUI, eg
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">timer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">1000</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F5</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">iteration</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (restart timer)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"K_ANY"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
 
=={{header|PicoLisp}}==
Line 689 ⟶ 1,018:
This will print a message after one second, then terminate the program after
another four seconds:
<langsyntaxhighlight PicoLisplang="picolisp">(alarm 1
(prinl "Exit in 4 seconds")
(alarm 4 (bye)) )</langsyntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
$timer = New-Object -TypeName System.Timers.Timer -Property @{Enabled=$true; Interval=1000; AutoReset=$true}
 
$action = {
$global:counter += 1
Write-Host “Event counter is ${counter}: $((Get-Date).ToString("hh:mm:ss"))”
if ($counter -ge $event.MessageData)
{
Write-Host “Timer stopped”
$timer.Stop()
}
}
 
$job = Register-ObjectEvent -InputObject $timer -MessageData 5 -SourceIdentifier Count -EventName Elapsed -Action $action
 
$global:counter = 0
& $job.Module {$global:counter}
</syntaxhighlight>
{{Out}}
<pre>
Event counter is 1: 04:58:04
Event counter is 2: 04:58:05
Event counter is 3: 04:58:06
Event counter is 4: 04:58:07
Event counter is 5: 04:58:08
Timer stopped
</pre>
 
=={{header|PureBasic}}==
<langsyntaxhighlight Purebasiclang="purebasic">OpenWindow (0, 10, 10, 150, 40, "Event Demo")
ButtonGadget (1, 10, 10, 35, 20, "Quit")
 
Line 705 ⟶ 1,063:
EndIf
ForEver</langsyntaxhighlight>
 
=={{header|Python}}==
 
<syntaxhighlight lang="python">
import threading
import time
 
 
def wait_for_event(event):
event.wait()
print("Thread: Got event")
 
e = threading.Event()
 
t = threading.Thread(target=wait_for_event, args=(e,))
t.start()
 
print("Main: Waiting one second")
time.sleep(1.0)
print("Main: Setting event")
e.set()
time.sleep(1.0)
print("Main: Done")
t.join()
</syntaxhighlight>
 
=={{header|Racket}}==
Line 716 ⟶ 1,099:
the task (since it's a useless value):
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 725 ⟶ 1,108:
 
(void (sync task)) ; wait for the task to be done before exiting
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{trans|Go}}
<syntaxhighlight lang="raku" line>note now, " program start";
my $event = Channel.new;
 
my $todo = start {
note now, " task start";
$event.receive;
note now, " event reset by task";
}
 
note now, " program sleeping";
sleep 1;
note now, " program signaling event";
$event.send(0);
await $todo;</syntaxhighlight>
{{out}}
<pre>Instant:1403880984.089974 program start
Instant:1403880984.095400 program sleeping
Instant:1403880984.095491 task start
Instant:1403880985.099381 program signaling event
Instant:1403880985.109395 event reset by task</pre>
 
See also [[Handle_a_signal#Raku]] for an example of using Supplies to do reactive programming based on events (Unix signals in this case).
 
=={{header|REXX}}==
Although REXX can be event driven, most events would probably have to be actively checked to see if the event occurs.
<br>Here is a &nbsp; ''time-driven'' &nbsp; example of events happening, based on specific timer ticks.
<langsyntaxhighlight lang="rexx">/*REXX program showsdemonstrates a method of handling events (this is time-drivena time─driven pgm). */
signal on halt /*allow the user to HALT (Break) the pgm.*/
parse arg timeEvent /*allow the "event" to be specified. */
if timeEvent='' then timeEvent= 5 /*if notNot specified,? Then use the default. */
 
event?: do forever /*determine if an event has occurred. */
theEvent= right(time(), 1) /*maybe it's an event, ─or─ maybe not.*/
if pos(theEvent, timeEvent)\==>0 then signal happening
end /*forever*/
 
say 'Control should never get here!' /*This is a logic no-no occurancecan─never─happen ! */
halt: say '════════════ program halted.'; exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────HAPPENING processing───────────────*/
happening: say 'an event occurred at' time()", the event is:" theEvent
do do while theEvent==right(time(), 1); /*processspin theuntil eventa heretic (a second) changes. */ nop;end
signal event? nop /*seereplace ifNOP another eventwith happened.the "process" code.*/</lang>
end /*while*/ /*NOP is a REXX statement, does nothing*/
'''output''' when using the input of: &nbsp; <tt> 1 3 5 0 7 9 </tt>
signal event? /*see if another event has happened. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> 1 &nbsp; 3 &nbsp; 5 &nbsp; 0 &nbsp; 7 &nbsp; 9 </tt>}}
<pre>
an event occurred at 16:13:29, the event is: 9
Line 764 ⟶ 1,175:
an event occurred at 16:13:51, the event is: 1
an event occurred at 16:13:53, the event is: 3
════════════ program halted.
</pre>
 
=={{header|Rust}}==
 
Rust ensures memory safety at compile-time without needing a garbage collector or runtime. There are several concurrency primitives in it's standard library.
 
<syntaxhighlight lang="rust">
use std::{sync::mpsc, thread, time::Duration};
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("[1] Starting");
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
println!("[2] Waiting for event");
rx.recv();
println!("[2] Received event");
});
thread::sleep(Duration::from_secs(1));
println!("[1] Sending event");
tx.send(())?;
thread::sleep(Duration::from_secs(1));
 
Ok(())
}
</syntaxhighlight>
 
=={{header|Tcl}}==
Tcl has been event-driven since 7.5, but only supported channel and timer events (plus variable traces, which can be used to create event-like entitites). With the addition of coroutines, it becomes much simpler to create general events:
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl"># Simple task framework built from coroutines
proc pause ms {
after $ms [info coroutine];yield
Line 823 ⟶ 1,258:
X signal
}
waitForTasksToFinish</langsyntaxhighlight>
Output:
<pre>waiting for event
Line 829 ⟶ 1,264:
received event</pre>
Of course, the classic way of writing this is much shorter, but intermingles the tasks:
<langsyntaxhighlight lang="tcl">after 1000 set X signalled
puts "waiting for event"
vwait X
puts "received event"</langsyntaxhighlight>
 
=={{header|Wren}}==
Wren-cli supports the scheduling of tasks using a timer.
 
The tasks to be executed are added to a list by the Scheduler class. The Timer.sleep method suspends the current fiber and signals the scheduler (by calling a private method) to execute the tasks one by one in their own fibers - in Wren only one fiber can execute at a time. The task results are then available to the main fiber on its resumption after Timer.sleep has completed.
<syntaxhighlight lang="wren">import "scheduler" for Scheduler
import "timer" for Timer
 
var a = 3
 
// add a task
Scheduler.add {
a = a * a
}
// add another task
Scheduler.add {
a = a + 1
}
 
System.print(a) // still 3
Timer.sleep(3000) // wait 3 seconds
System.print(a) // now 3 * 3 + 1 = 10</syntaxhighlight>
 
{{out}}
<pre>
3
10
</pre>
 
=={{header|Yabasic}}==
{{trans|Gambas}}
<syntaxhighlight lang="yabasic">
sub Timer1_Timer()
print Time$
end sub
</syntaxhighlight>
 
 
=={{header|zkl}}==
zkl provides an Atomics library for things like this. Events are async, waiting for an event doesn't poll.
<langsyntaxhighlight lang="zkl">var event=Atomic.Bool(); // False
// create thread waiting for event
fcn(event){event.wait(); println(vm," ping!")}.launch(event);
Atomic.sleep(1);
event.set();
println("done")</langsyntaxhighlight>
{{out}}
<pre>
1,981

edits