Szymański's algorithm: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added FreeBasic)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(2 intermediate revisions by 2 users not shown)
Line 22:
https://en.wikipedia.org/wiki/Szyma%C5%84ski%27s_algorithm
"""
 
=={{header|C#}}==
{{trans|Julia}}
<syntaxhighlight lang="C#">
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
 
class Program
{
private static ConcurrentDictionary<int, int> dict = new ConcurrentDictionary<int, int>();
private static int criticalValue = 1;
private static readonly object lockObject = new object();
 
static void Main(string[] args)
{
TestSzymanski(20);
}
 
static int Flag(int id)
{
return dict.GetOrAdd(id, 0);
}
 
static void RunSzymanski(int id, int[] allszy)
{
var others = allszy.Where(t => t != id).ToArray();
dict[id] = 1; // Standing outside waiting room
while (others.Any(t => Flag(t) >= 3))
{
Thread.Yield();
}
dict[id] = 3; // Standing in doorway
if (others.Any(t => Flag(t) == 1))
{
dict[id] = 2; // Waiting for other processes to enter
while (!others.Any(t => Flag(t) == 4))
{
Thread.Yield();
}
}
dict[id] = 4; // The door is closed
foreach (var t in others)
{
if (t >= id) continue;
while (Flag(t) > 1)
{
Thread.Yield();
}
}
 
// critical section
lock (lockObject)
{
criticalValue += id * 3;
criticalValue /= 2;
Console.WriteLine($"Thread {id} changed the critical value to {criticalValue}.");
}
// end critical section
 
// Exit protocol
foreach (var t in others)
{
if (t <= id) continue;
while (!new[] { 0, 1, 4 }.Contains(Flag(t)))
{
Thread.Yield();
}
}
dict[id] = 0; // Leave. Reopen door if nobody is still in the waiting room
}
 
static void TestSzymanski(int N)
{
int[] allszy = Enumerable.Range(1, N).ToArray();
var threads = allszy.Select(i => new Thread(() => RunSzymanski(i, allszy))).ToArray();
 
foreach (var thread in threads)
{
thread.Start();
}
 
foreach (var thread in threads)
{
thread.Join();
}
}
}
</syntaxhighlight>
{{out}}
<pre>
Thread 1 changed the critical value to 2.
Thread 2 changed the critical value to 4.
Thread 3 changed the critical value to 6.
Thread 4 changed the critical value to 9.
Thread 5 changed the critical value to 12.
Thread 6 changed the critical value to 15.
Thread 7 changed the critical value to 18.
Thread 8 changed the critical value to 21.
Thread 9 changed the critical value to 24.
Thread 10 changed the critical value to 27.
Thread 11 changed the critical value to 30.
Thread 12 changed the critical value to 33.
Thread 13 changed the critical value to 36.
Thread 14 changed the critical value to 39.
Thread 15 changed the critical value to 42.
Thread 16 changed the critical value to 45.
Thread 17 changed the critical value to 48.
Thread 18 changed the critical value to 51.
Thread 19 changed the critical value to 54.
Thread 20 changed the critical value to 57.
 
</pre>
 
 
=={{header|FreeBASIC}}==
Line 244 ⟶ 359:
Thread 3 changed the critical value from 10 (+3*3=19)/2 to 9
</pre>
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" line># 20230822 Raku programming solution
 
use OO::Monitors;
 
my \N = 10;
 
monitor Szymański {
 
has @.tasks;
my $critical = 0;
 
method runSzymański($id) {
@.tasks[$id] = 1;
( my @others = @.tasks ).splice: $id,1;
until @others.all ~~ 0|1|2 { $*THREAD.yield }
@.tasks[$id] = 3;
if @others.any ~~ 1 {
@.tasks[$id] = 2;
until @others.any ~~ 4 { $*THREAD.yield }
}
@.tasks[$id] = 4;
until @.tasks[^$id].all ~~ 0|1 { $*THREAD.yield }
$critical = ((my $previous = $critical) + $id * 3) div 2;
say "Thread $id changed the critical value from $previous to $critical";
until @.tasks[$id^..*-1].all ~~ 0|1|4 { $*THREAD.yield }
@.tasks[$id] = 0
}
}
 
my $flag = Szymański.new: tasks => 0 xx N;
await Promise.allof( ^N .pick(*).map: { start { $flag.runSzymański: $_ } } );</syntaxhighlight>
{{out}}
<pre>Thread 6 changed the critical value from 0 to 9
Thread 1 changed the critical value from 9 to 6
Thread 5 changed the critical value from 6 to 10
Thread 4 changed the critical value from 10 to 11
Thread 7 changed the critical value from 11 to 16
Thread 9 changed the critical value from 16 to 21
Thread 8 changed the critical value from 21 to 22
Thread 3 changed the critical value from 22 to 15
Thread 2 changed the critical value from 15 to 10
Thread 0 changed the critical value from 10 to 5</pre>
 
=={{header|Wren}}==
Line 255 ⟶ 414:
 
As Wren fibers don't have an id property, we pass one as an argument when starting the fiber.
<syntaxhighlight lang="ecmascriptwren">import "random" for Random
 
var rand = Random.new()
9,488

edits