Mutex: Difference between revisions

1,682 bytes added ,  3 years ago
Add source for Rust
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
(Add source for Rust)
Line 294:
 
task() ->
Mutex = erlang:spawn( fun() -> loop() end ),
[erlang:spawn(fun() -> random:seed( X, 0, 0 ), print(Mutex, X, 3) end) || X <- lists:seq(1, 3)].
 
 
 
loop() ->
receive
{acquire, Pid} ->
Pid ! {access, erlang:self()},
receive
{release, Pid} -> loop()
end
end.
 
mutex_acquire( Pid ) ->
Pid ! {acquire, erlang:self()},
receive
{access, Pid} -> ok
end.
 
mutex_release( Pid ) -> Pid ! {release, erlang:self()}.
Line 318:
print( _Mutex, _N, 0 ) -> ok;
print( Mutex, N, M ) ->
timer:sleep( random:uniform(100) ),
mutex_acquire( Mutex ),
io:fwrite( "Print ~p: ", [N] ),
[print_slow(X) || X <- lists:seq(1, 3)],
io:nl(),
mutex_release( Mutex ),
print( Mutex, N, M - 1 ).
 
print_slow( X ) ->
io:fwrite( " ~p", [X] ),
timer:sleep( 100 ).
</lang>
{{out}}
Line 768:
meth test
lock
{Show exclusive}
end
end
Line 895:
 
class res_thread(threading.Thread):
def run(self):
global res
n = self.getName()
for i in range(1, 4):
# acquire a resource if available and work hard
# for 2 seconds. if all res are occupied, block
# and wait
sema.acquire()
res = res - 1
print n, "+ res count", res
sleep(2)
 
# after done with resource, return it to pool and flag so
res = res + 1
print n, "- res count", res
sema.release()
 
# create 4 threads, each acquire resorce and work
for i in range(1, 5):
t = res_thread()
t.start()</lang>
 
=={{header|Racket}}==
Line 950:
 
$lock.protect: { your-ad-here() }</lang>
Locks are reentrant. You may explicitly lock and unlock them, but the syntax above guarantees the lock will be unlocked on scope exit, even if by thrown exception or other exotic control flow. That being said, direct use of locks is discouraged in Perl  6 in favor of promises, channels, and supplies, which offer better composable semantics.
 
=={{header|Ruby}}==
Line 983:
do critical stuff
end</lang>
 
=={{header|Rust}}==
Rust's standard library provides <tt>std::sync::Mutex</tt>. Locking the mutex
returns a guard that allows accessing the shared data exclusively. When the
guard goes out of its scope (and is dropped), the mutex gets unlocked again.
 
Following small program demonstrates using the mutex with two threads that
append to a shared string.
 
<lang rust>use std::{
sync::{Arc, Mutex},
thread,
time::Duration,
};
 
fn main() {
let shared = Arc::new(Mutex::new(String::new()));
 
let handle1 = {
let value = shared.clone();
thread::spawn(move || {
for _ in 0..20 {
thread::sleep(Duration::from_millis(200));
// The guard is valid until the end of the block
let mut guard = value.lock().unwrap();
guard.push_str("A");
println!("{}", guard);
}
})
};
 
let handle2 = {
let value = shared.clone();
thread::spawn(move || {
for _ in 0..20 {
thread::sleep(Duration::from_millis(300));
 
{
// Making the guard scope explicit here
let mut guard = value.lock().unwrap();
guard.push_str("B");
println!("{}", guard);
}
}
})
};
 
handle1.join().ok();
handle2.join().ok();
shared.lock().ok().map_or((), |it| println!("Done: {}", it));
}
</lang>
 
=={{header|Tcl}}==
Anonymous user