Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Backgroundthreads mit Sinatra?
BeitragVerfasst: 15 Mai 2015, 10:38 
Offline
ri
Benutzeravatar

Registriert: 04 Okt 2005, 10:42
Beiträge: 740
Wohnort: Wien
Ich würde gerne in einer Sinatra App mittels der routen get '/on' und get '/off' einen Thread starten und stoppen.

Wenn ich im Browser localhost:4567/on aufrufe soll z.B. "on" angezeigt werden und ein Thread gestartet werden (es handelt sich um einen loop, der endlos laufen soll)

Wenn ich im Browser localhost:4567/off aufrufe soll der Thread einfach beendet werden.

Wie geht man hier am besten vor? Kann mir jemand dazu einen Tipp geben?


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Backgroundthreads mit Sinatra?
BeitragVerfasst: 15 Mai 2015, 11:00 
Offline
ri
Benutzeravatar

Registriert: 04 Okt 2005, 10:42
Beiträge: 740
Wohnort: Wien
Ich habe jetzt eine Variable definiert, ob der thread was machen soll und oder nicht, und prüfe innerhalb vom thread, ob diese Variable true oder false ist und lass den thread jetzt ab Start der Sinatra App dauernd laufen.

Elegant ist das nicht, aber es funktioniert erstmal.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Backgroundthreads mit Sinatra?
BeitragVerfasst: 15 Mai 2015, 16:49 
Offline
Interpreter
Benutzeravatar

Registriert: 18 Sep 2008, 22:32
Beiträge: 1821
Wohnort: NRW → UN
Gekkonier hat geschrieben:
Ich habe jetzt eine Variable definiert, ob der thread was machen soll und oder nicht, und prüfe innerhalb vom thread, ob diese Variable true oder false ist und lass den thread jetzt ab Start der Sinatra App dauernd laufen.


Das ist eigentlich sogar der richtige Weg, wenn auch nicht ganz so. Du musst aber darauf achten, die Variable mit einer Mutex zu schützen, da sonst gleichzeitige Zugriffe möglich sind.

Sinatra spielt dabei nur eine untergeordnete Rolle, du kannst dich auf die ganz normalen Ruby-Kenntnisse verlassen. Das Gerüst sieht etwa so aus:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Foo

def initialize
@mythread = nil
@stopthread = false
@mutex = Mutex.new
end

def start
return if @mythread
@mythread = Thread.new do
loop do
break if @mutex.synchronize{@stopthread}
do_your_things
end
end
end

def stop
@mutex.synchronize{@stopthread = true}
end

def stop_wait
stop
@mythread.join
@mythread = nil
end

end

f = Foo.new
f.start
f.stop_wait


@stopthread ist in diesem Code eine geteilte Ressource (shared resource), auf die von mehreren Threads zugegriffen wird. Um ein Wettrennen um den Zugriff (race condition) zu vermeiden, musst du eine Mutex verwenden, die sicherstellt, dass immer nur ein Thread die geteilte Ressource verwenden kann. Die Verwendung einer solchen Variable ist das anerkannte Muster, um Threads von außen zu stoppen. Du kannst zwar auch das hier machen:



1
2
3
4
  def stop_force
@mythread.raise(RuntimeError.new("Forcing termination"))
@mythread = nil
end


Das ist aber ganz schlechter Stil und es führt zu schwer vorhersehbaren Ergebnissen, von außen in einen Thread eine Exception zu „injizieren“.

Vale,
Quintus

_________________
Habe den Mut, dich deines eigenen Verstandes zu bedienen! — Immanuel Kant

Ich bin freischaffender Softwareentwickler und freue mich über jedes neue Projekt. Kontaktinformation auf meiner Website.

Mein Blog | GitHub-Profil | Auf Twitter: @qquintilianus | PGP/GPG-Schlüssel: B1FE 958E D5E8 468E AA20 8F4B F1D8 799F BCC8 BC4F


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Backgroundthreads mit Sinatra?
BeitragVerfasst: 16 Mai 2015, 19:05 
Offline
ri
Benutzeravatar

Registriert: 04 Okt 2005, 10:42
Beiträge: 740
Wohnort: Wien
Herzlichen Dank für die umfassende Erklärung, ich werde das heute abends testen.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Backgroundthreads mit Sinatra?
BeitragVerfasst: 16 Mai 2015, 23:21 
Offline
ri
Benutzeravatar

Registriert: 04 Okt 2005, 10:42
Beiträge: 740
Wohnort: Wien
Danke, das funktioniert sehr gut!

Einen Fehler konnte ich entdecken: in der Methode start sollte man noch am Begin ein @mutex.synchronize{@stopthread = false} machen, sonst wird jedesmal der loop gebreaked.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Backgroundthreads mit Sinatra?
BeitragVerfasst: 17 Mai 2015, 09:35 
Offline
Interpreter
Benutzeravatar

Registriert: 18 Sep 2008, 22:32
Beiträge: 1821
Wohnort: NRW → UN
Gekkonier hat geschrieben:
in der Methode start sollte man noch am Begin ein @mutex.synchronize{@stopthread = false} machen, sonst wird jedesmal der loop gebreaked.


Nur dann, wenn du den Thread startest, bevor du @stopthread setzt. In meinem Code existiert zu dem Zeitpunkt, an dem die Klasse Foo instanziiert wird, nur ein einziger Thread, der Hauptthread. Erst später wird ein weiterer Thread gestartet, und @stopthread damit zu einer shared resource. Daher ist eine Mutex in initialize oben nicht notwendig. Weil aber unitialisierte Instanzvariablen nil sind, sollte das eigentlich selbst dann nicht zur Abbruchbedingung führen.

Ich vermute, bei dir ist so etwas entstanden:



1
2
3
@mutex = Mutex.new
@thread = Thread.new{...break if @mutex.synchronize{@stopthread}...}
@stopthread = false


Dann hast du natürlich wieder den Wettlauf. Dann kann es aber auch passieren, dass der Thread zuerst drankommt und @stopthread uninitialisiert, sprich nil, vorfindet.

Vale,
Quintus

_________________
Habe den Mut, dich deines eigenen Verstandes zu bedienen! — Immanuel Kant

Ich bin freischaffender Softwareentwickler und freue mich über jedes neue Projekt. Kontaktinformation auf meiner Website.

Mein Blog | GitHub-Profil | Auf Twitter: @qquintilianus | PGP/GPG-Schlüssel: B1FE 958E D5E8 468E AA20 8F4B F1D8 799F BCC8 BC4F


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach: