September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,56 +0,0 @@
package main
import (
"log"
"os"
"sync"
"time"
)
var fmt = log.New(os.Stdout, "", 0)
func main() {
// three operations per task description
acquire := make(chan int)
release := make(chan int)
count := make(chan chan int)
// library analogy per WP article
go librarian(acquire, release, count, 10)
nStudents := 20
var studied sync.WaitGroup
studied.Add(nStudents)
for i := 0; i < nStudents; i++ {
go student(acquire, release, count, &studied)
}
// wait until all students have studied before terminating program
studied.Wait()
}
func librarian(a, r chan int, c chan chan int, count int) {
p := a // acquire operation is served or not depending on count
for {
select {
case <-p: // acquire/p/wait operation
count--
if count == 0 {
p = nil
}
case <-r: // release/v operation
count++
p = a
case cc := <-c: // count operation
cc <- count
}
}
}
func student(a, r chan int, c chan chan int, studied *sync.WaitGroup) {
cc := make(chan int)
a <- 0 // acquire
c <- cc // request count
fmt.Printf("Room entered. Count is %d. Studying...\n", <-cc)
time.Sleep(2 * time.Second) // sleep per task description
r <- 0 // release
studied.Done() // signal done
}

View file

@ -0,0 +1,69 @@
sequence sems = {}
constant COUNTER = 1, QUEUE = 2
function semaphore(integer n)
if n>0 then
sems = append(sems,{n,{}})
return length(sems)
else
return 0
end if
end function
procedure acquire(integer id)
if sems[id][COUNTER]=0 then
task_suspend(task_self())
sems[id][QUEUE] &= task_self()
task_yield()
end if
sems[id][COUNTER] -= 1
end procedure
procedure release(integer id)
sems[id][COUNTER] += 1
if length(sems[id][QUEUE])>0 then
task_schedule(sems[id][QUEUE][1],1)
sems[id][QUEUE] = sems[id][QUEUE][2..$]
end if
end procedure
function count(integer id)
return sems[id][COUNTER]
end function
procedure delay(atom delaytime)
atom t = time()
while time()-t<delaytime do
task_yield()
end while
end procedure
integer sem = semaphore(4)
procedure worker()
acquire(sem)
printf(1,"- Task %d acquired semaphore.\n",task_self())
delay(2)
release(sem)
printf(1,"+ Task %d released semaphore.\n",task_self())
end procedure
for i=1 to 10 do
integer task = task_create(routine_id("worker"),{})
task_schedule(task,1)
task_yield()
end for
integer sc = 0
atom t0 = time()+1
while length(task_list())>1 do
task_yield()
integer scnew = count(sem)
if scnew!=sc
or time()>t0 then
sc = scnew
printf(1,"Semaphore count now %d\n",{sc})
t0 = time()+2
end if
end while
?"done"

View file

@ -0,0 +1,44 @@
require 'thread'
# Simple Semaphore implementation
class Semaphore
def initialize(size = 1)
@queue = SizedQueue.new(size)
size.times { acquire }
end
def acquire
tap { @queue.push(nil) }
end
def release
tap { @queue.pop }
end
# @return [Integer]
def count
@queue.length
end
def synchronize
release
yield
ensure
acquire
end
end
def foo(id, sem)
sem.synchronize do
puts "Thread #{id} Acquired lock"
sleep(2)
end
end
threads = []
n = 5
s = Semaphore.new(3)
n.times do |i|
threads << Thread.new { foo i, s }
end
threads.each(&:join)

View file

@ -0,0 +1,8 @@
fcn job(name,sem){
name.println(" wait"); sem.acquire();
name.println(" go"); Atomic.sleep(2);
sem.release(); name.println(" done")
}
// start 3 threads using the same semphore
s:=Thread.Semaphore(1);
job.launch("1",s); job.launch("2",s); job.launch("3",s);