2016-04-23 11 views
0

はじめに私は自分自身を好転させるのが大好きですが、これは学習目的の練習ですが、この演習の情報を最終的に取り上げて、ここに振る舞いをカプセル化したマクロを実装したいと思います。それで、letのalotを使っている理由は何もまだ確定されておらず、定義があまりにも重いためです。協調スレッディング、割り当てなし

ですから、別の協力のスレッド構築物のすべての種類を実装するための呼び出し/ ccのを使用することができ、かつ使用してイムスレッドのモデルは、一般的に次のとおりです。

(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 

そして、これまでのところ、これは実際には本当によく働きます。

私の問題では、いくつかの基本ケース、exit句のあるスレッド、スレッドがないスレッド、再開できないスレッド、または1回のショット(基本的には関数呼び出しですが、一貫性のある元気無担当者とそう

(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 
     )) 

)それは「スレッド」だけではなく、関数の呼び出しにしておく必要がありそう?なぜそれをメインスレッドのスレッドの1つとして無限ループに走らせるのでしょうか?コメント行との例から

出力:

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 

非コメント:あなたが使用している実装

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???? 

答えて

0

わからないが、私はちょうど式をコメントアウト無限ループを得ることができませんでした。 (私はラケットを含むR6RS実装のカップルを、使用しました)

を、物事を簡単にするために、私はこのようなコードを剥奪しました:

#!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 '()))) 

ポイントが*1の戻り続きです。プロシージャspawn-threadno-repsプロシージャを実行し、no-repsは次のプロセスがmainのspawn-threadをコールしている特定の継続を戻します。したがって、この文脈でno-repsが実際に行うことは、メインスレッドを複製することです。 Racketで実行される次の実行結果は、それを示しています:

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 
---%