Имитация каналов из Go

Только технические вопросы по ЯОС и MINOS. Терминология и прочее - в других форумах.
Ответить
БудДен
Сообщения: 2839
Зарегистрирован: 07.10.18 14:01

Имитация каналов из Go

Сообщение БудДен » 09.11.20 14:39

(C) Sergey Durmanov, [09.11.20 09:14]
ты придаёшь слишком много значения мелочам. а каналы в го это частный случай для активного оберона

Sergey Durmanov, [09.11.20 09:19]
допустим, у нас есть такой код на go

Sergey Durmanov, [09.11.20 09:21]
package main

Код: Выделить всё

import "fmt"

func squares(c chan int) {
    for i := 0; i <= 9; i++ {
        c <- i * i
    }

    close(c) // close channel
}

func main() {
    fmt.Println("main() started")
    c := make(chan int)

    go squares(c) // start goroutine

    // periodic block/unblock of main goroutine until chanel closes
    for val := range c {
        fmt.Println(val)
    }

    fmt.Println("main() stopped")
}

Sergey Durmanov, [09.11.20 09:22]
мы сделаем похожее на активном обероне, реализовав некое подобие каналов

Sergey Durmanov, [09.11.20 09:22]
вот наш канал

Sergey Durmanov, [09.11.20 09:22]
module IntegerChannel;

type
  T* = object
    var data: integer;
    var hasData, isClosed: boolean;

    procedure & Init*;
    begin
      data := 0;
      hasData := false;
      isClosed := false;
    end Init;

    procedure Send(value: integer) : boolean;
    begin { EXCLUSIVE }
      await( ~hasData or isClosed );
      if ~isClosed then
        data := value;
        hasData := true;
        return true;
      end;
      trace("send on closed channel");
      return false;
    end Send;

    procedure Receive( var x: integer ): boolean;
    begin { EXCLUSIVE }
      await( hasData or isClosed  );
      if hasData then
        hasData := false;
        x := data;
        return true;
      end;
      trace("receive from a closed channel");
      return false;
    end Receive;

    procedure Close*;
    begin { EXCLUSIVE }
      isClosed := true;
    end Close;

    procedure HasData*(): boolean;
    begin { EXCLUSIVE }
      return ~isClosed or hasData;
    end HasData;
  end T;

  operator "<<"* (c: T; x: integer);
  begin
    ignore c.Send(x);
  end "<<";

  operator "<<"* (var x: integer; c: T);
  begin
    ignore c.Receive(x);
  end "<<";

end IntegerChannel.
Sergey Durmanov, [09.11.20 09:24]
и программа примерно такая

Sergey Durmanov, [09.11.20 09:24]

Код: Выделить всё

module ChannelTest;
import IntegerChannel;

type
  Squares = object
  var c: IntegerChannel.T;
    procedure & Init( c: IntegerChannel.T );
    begin
      self.c := c;
    end Init;
  begin { ACTIVE }
    var i: integer;
    for i := 0 to 9 do
      c << i * i;
    end;
    c.Close;
  end Squares;

  procedure main*;
  var x: integer;
  begin
    trace("main started");
    var c := new IntegerChannel.T();

    ignore new Squares( c );

    while c.HasData() do
      x << c;
      trace(x);
    end;
    trace("main stopped");
  end main;
end ChannelTest.

ChannelTest.main~

System.FreeDownTo ChannelTest~

Ответить