2016-04-23 13 views
0

Vorwort Ich liebe es, meine eigenen zu rollen, dies ist eine Übung für Lernzwecke, aber ich möchte die Informationen aus dieser Übung schließlich nehmen und einige Makros implementieren, die die Verhaltensweisen hier kapseln. Deshalb verwende ich sehr viele let, weil noch nichts finalisiert ist und definiert sind zu "schwer".Cooperative Threading, Keine Zuordnung

So können Sie Anruf/cc verwenden, um alle Arten von verschiedenen kooperativen Threading-Konstrukten zu implementieren, und das Modell für einen Thread, der mit im, ist in der Regel:

(let ((generic-thread 
     (lambda (cc) 
     (let loop ((cc cc)) 
      (printf "doing stuff~N") 
      (loop (call/cc cc)))))) ;this is the magic, it calls the calling continuation 
    (let loop ((its 0)    ;and then loops with the result of that 
      (cc generic-thread)) ;so when its resumed, it still has its new state 
    (if (< its 10) 
     (loop (+ its 1) (call/cc cc))))) ;just repeats the procedure for the demonstration 

Und so weit das funktioniert wirklich gut eigentlich.

Also in meinem Problem, ich fühle mich identifiziert ein paar Basisfälle, Threads mit einer Exit-Klausel, diejenigen ohne sie und Threads, die nicht fortgesetzt werden können, oder eine Aufnahmen (im Wesentlichen nur ein Funktionsaufruf, aber ich möchte sein konsistent, so dass es in einem „Faden“ sein und einen Funktionsaufruf nicht nur)

(let ((spawn-thread 
     (lambda (it . args) 
     (call/cc (apply it args)))) 

     (main 
     (lambda (label reps . sequence) 
     ;for consistency, main is also a thread, but does not need to be 
     ;this will take a number of repetitions, and a sequence of continuations 
     ;to call, pushing the continuation returned from the top continuation in 
     ;sequence to the end, and then calling the loop again 
      (lambda (cc) 
      (let loop ((sequence sequence) (state 0)) 
       (printf "IN MAIN THREAD STATE: ~A~N---" state) 
       (if (< state reps) ;this is essentially a queue but without assignment 
        (loop `(,@(cdr sequence) ,(call/cc (car sequence))) 
         (+ state 1))))))) 

     (with-exit 
     (lambda (label data) 
     ;thread with exit case 
     (lambda (cc) 
      (let loop ((cc cc) (done (lambda() #f)) (state 0)) 
      (cond ((done) (cc data)) ;if done was replaced with something else that         
             ;could at some point return true, this is where 
             ;the thread would exit 
        (else    
        (printf "IN THREAD ~A TYPE: WITH-EXIT STATE: ~A~N" label state) 
        (loop (call/cc cc) done (+ state 1)))))))) 

     (no-exit 
     (lambda (label data) 
     ;no exit case, can be resumed arbitrarily 
      (lambda (cc) 
      (let loop ((cc cc) (state 0)) 
       (printf "IN THREAD ~A TYPE: NO-EXIT STATE: ~A~N" label state) 
       (loop (call/cc cc) (+ state 1)))))) 


     (no-reps 
     (lambda (label data) 
     ;breaks it for some reason? 
     ;would be called, do its stuff and then 
     ;go back to the calling continuation 
     (lambda (cc)    
      (printf "IN THREAD ~A TYPE: NO-REPS~N" label) 
      (call/cc cc))))) 

    (spawn-thread main 'main 10 
     (spawn-thread with-exit 1 '()) 
     (spawn-thread no-exit 2 '()) 
     (spawn-thread with-exit 3 '()) 
     ;(spawn-thread no-reps 4 '())) uncomment to see error 
     )) 

so whats up ohne-Wiederholungen? Warum führt das Ausführen als einer der Threads in main zu einer Endlosschleife?

Ausgabe von Beispiel mit kommentierten Zeile:

IN THREAD 1 TYPE: WITH-EXIT STATE: 0 
IN THREAD 2 TYPE: NO-EXIT STATE: 0 
IN THREAD 3 TYPE: WITH-EXIT STATE: 0 
IN MAIN THREAD STATE: 0 
---IN THREAD 1 TYPE: WITH-EXIT STATE: 1 
IN MAIN THREAD STATE: 1 
---IN THREAD 2 TYPE: NO-EXIT STATE: 1 
IN MAIN THREAD STATE: 2 
---IN THREAD 3 TYPE: WITH-EXIT STATE: 1 
IN MAIN THREAD STATE: 3 
---IN THREAD 1 TYPE: WITH-EXIT STATE: 2 
IN MAIN THREAD STATE: 4 
---IN THREAD 2 TYPE: NO-EXIT STATE: 2 
IN MAIN THREAD STATE: 5 
---IN THREAD 3 TYPE: WITH-EXIT STATE: 2 
IN MAIN THREAD STATE: 6 
---IN THREAD 1 TYPE: WITH-EXIT STATE: 3 
IN MAIN THREAD STATE: 7 
---IN THREAD 2 TYPE: NO-EXIT STATE: 3 
IN MAIN THREAD STATE: 8 
---IN THREAD 3 TYPE: WITH-EXIT STATE: 3 
IN MAIN THREAD STATE: 9 
---IN THREAD 1 TYPE: WITH-EXIT STATE: 4 
IN MAIN THREAD STATE: 10 

unkommentiert:

IN THREAD 1 TYPE: WITH-EXIT STATE: 0 
IN THREAD 2 TYPE: NO-EXIT STATE: 0 
IN THREAD 3 TYPE: WITH-EXIT STATE: 0 
IN THREAD 4 TYPE: NO-REPS 
IN MAIN THREAD STATE: 0 
---IN THREAD 1 TYPE: WITH-EXIT STATE: 1 
IN MAIN THREAD STATE: 1 
---IN THREAD 2 TYPE: NO-EXIT STATE: 1 
IN MAIN THREAD STATE: 2 
---IN THREAD 3 TYPE: WITH-EXIT STATE: 1 
IN MAIN THREAD STATE: 3 
---IN MAIN THREAD STATE: 0 
---IN THREAD 1 TYPE: WITH-EXIT STATE: 1 
......... ;profit???? 

Antwort

0

nicht sicher, welche Implementierung Sie verwenden, aber ich konnte nicht Endlosschleife bekommen nur den Ausdruck uncommenting. (. Ich habe verwendet paar R6RS Implementierungen, einschließlich Racket)

die Dinge einfacher, habe ich Ihren Code wie folgt ausgezogen:

#!r6rs 
(import (rnrs)) 

(define (print . args) (for-each display args) (newline)) 

(let ((spawn-thread 
     (lambda (it . args) 
     (call/cc (apply it args)))) 
     (main 
     (lambda (label reps . sequence) 
     (lambda (cc) 
      (print sequence) 
      (let loop ((sequence sequence) (state 0)) 
      (print "IN MAIN THREAD STATE: " state) 
      (display "---") 
      (if (< state reps) 
       (let ((next `(,@(cdr sequence) ,(call/cc (car sequence))))) 
        (loop next (+ state 1)))))))) 
     (no-reps 
     (lambda (label data) 
     (lambda (cc) 
      (print "IN THREAD "label" TYPE: NO-REPS") 
      (call/cc cc))))) 
    (spawn-thread main 'main 10 
       ;; *1 
       (spawn-thread no-reps 4 '()))) 

Der Punkt ist, die Rückkehr Fortsetzung *1. Die Prozedur spawn-thread führt die Prozedur no-reps aus, und no-reps gibt die angegebene Fortsetzung zurück, deren nächster Prozess spawn-thread von main aufruft. Was also in diesem Zusammenhang no-reps tatsächlich tut, ist das Duplizieren des Hauptthreads. Das folgende Ausführungsergebnis, ausgeführt mit Racket, zeigt es an:

IN THREAD 4 TYPE: NO-REPS 
{#<continuation>} 
IN MAIN THREAD STATE: 0 
---{#<continuation>} 
IN MAIN THREAD STATE: 0 
---IN MAIN THREAD STATE: 1 
---IN MAIN THREAD STATE: 1 
---IN MAIN THREAD STATE: 2 
---IN MAIN THREAD STATE: 2 
---IN MAIN THREAD STATE: 3 
---IN MAIN THREAD STATE: 3 
---IN MAIN THREAD STATE: 4 
---IN MAIN THREAD STATE: 4 
---IN MAIN THREAD STATE: 5 
---IN MAIN THREAD STATE: 5 
---IN MAIN THREAD STATE: 6 
---IN MAIN THREAD STATE: 6 
---IN MAIN THREAD STATE: 7 
---IN MAIN THREAD STATE: 7 
---IN MAIN THREAD STATE: 8 
---IN MAIN THREAD STATE: 8 
---IN MAIN THREAD STATE: 9 
---IN MAIN THREAD STATE: 9 
---IN MAIN THREAD STATE: 10 
---%