Neko多线程

1 创建线程

var t1 = Thread.create(sendMsgs);
var t2 = Thread.create(getMsgs);

create后立即执行,且与主线程时序无关

2 消息共享与堵塞

2.1 readMessage

readMessage(true)则堵塞直到向其sendMessage, 例如:

private function main():Void {
    var t1 = Thread.create(sendMsgs);
    var t2 = Thread.create(getMsgs);
    // give thread1 ref to main thread and thread2
    t1.sendMessage(Thread.current());
    t1.sendMessage(t2);
    // give thread2 a ref to main thread
    t2.sendMessage(Thread.current());
    // wait for them to finish
    trace(Thread.readMessage(true));
    trace(Thread.readMessage(true));
    Lib.println("done\n");
}

static function sendMsgs() {
    // get ref to main and thread2
    var main:Thread = Thread.readMessage(true);
    var t2:Thread   = Thread.readMessage(true);
    for (ii in 0...5) {
        Lib.println("t1 sending: " + ii);
        t2.sendMessage(ii);
        Sys.sleep(.5);
    }
    main.sendMessage("thread1 done");
}

// thread2 gets messages sent by thread1
static function getMsgs() {
    // get ref to main
    var main:Thread = Thread.readMessage(true);
    for (ii in 0...5) {
        Lib.println("t2 waiting for msg");
        Lib.println("t2 got: " + Thread.readMessage(true));
    }
    main.sendMessage("thread2 done");
}

2.2 Deque

pop(true)则堵塞直到向其push, 例如:

static function main() {
    // create deque for passing data
    var obj = new Deque<Int>();
    // create two thread, keep references
    Lib.println("Shared Deque Example");
    var t1 = Thread.create(sendMsgs);
    var t2 = Thread.create(getMsgs);
    // give each thread ref to main thread and deque
    t1.sendMessage(Thread.current());
    t1.sendMessage(obj);
    t2.sendMessage(Thread.current());
    t2.sendMessage(obj);
    // wait for them to finish
    Thread.readMessage(true);
    Thread.readMessage(true);
    Lib.println("done\n");
}

// thread1 sends messages to thread2
static function sendMsgs() {
    // get ref to main and deque
    var main:Thread    = Thread.readMessage(true);
    var obj:Deque<Int> = Thread.readMessage(true);
    for (ii in 0...5) {
        Lib.println("t1 pushing " + ii);
        obj.push(ii);
        Sys.sleep(.5);
    }
    main.sendMessage("thread1 done");
}

// thread2 gets messages sent by thread1
static function getMsgs() {
    // get ref to main thread and deque
    var main:Thread    = Thread.readMessage(true);
    var obj:Deque<Int> = Thread.readMessage(true);
    for (ii in 0...5) {
        Lib.println("t2 waiting for msg");
        Lib.println("t2 got: " + obj.pop(true));
    }
    main.sendMessage("thread2 done");
}

2.3 自定义共享数据类型

读写共享数据类型时需用 Mutex().acquire() 加锁,用 Mutex().release() 释放, 例如:

import neko.vm.Thread;
import neko.vm.Mutex;
import neko.Lib;
import neko.Sys;

// an object to share between threads
class Obj {
  public var m:Mutex;
  public var val(getVal,setVal):Int;
  public function new() {
    m = new Mutex();
    val = 0; 
  }

  private function getVal() {
    m.acquire();
    var ret = val;
    m.release();
    return ret;
  }

  private function setVal(v:Int) {
    m.acquire();
    val = v;
    m.release();
    return v;
  }
}

class UseMutex {
  static function main() {
    // create object to be shared
    var obj:Obj = new Obj();
    // create two thread, keep references
    Lib.println("Shared Object Example");
    var t1 = Thread.create(sendMsgs);
    var t2 = Thread.create(getMsgs);
    // give each thread ref to main thread and shared object
    t1.sendMessage(Thread.current());
    t1.sendMessage(obj);
    t2.sendMessage(Thread.current());
    t2.sendMessage(obj);
    // wait for them to finish
    Thread.readMessage(true);
    Thread.readMessage(true);
    Lib.println("done\n");
  }

  // thread1 sends messages to thread2
  static function sendMsgs() {
    // get ref to main and thread2
    var main:Thread = Thread.readMessage(true);
    var obj:Obj     = Thread.readMessage(true);
    for (ii in 0...5) {
      Lib.println("t1 setting" + ii);
      obj.val = ii;
      Sys.sleep(.5);
    }
    main.sendMessage("thread1 done");
  }

  // thread2 gets messages sent by thread1
  static function getMsgs() {
    var main:Thread = Thread.readMessage(true);
    var obj:Obj     = Thread.readMessage(true);
    var ii = 0;
    while (ii != 4) {
      ii = obj.val;
      Lib.println("t2 got: " + ii);
      Sys.sleep(.3);
    }
    main.sendMessage("thread2 done");
  }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注