Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Concurrency 为什么需要两个双向通道来实现单元的服务器协议?_Concurrency_F#_Hopac - Fatal编程技术网

Concurrency 为什么需要两个双向通道来实现单元的服务器协议?

Concurrency 为什么需要两个双向通道来实现单元的服务器协议?,concurrency,f#,hopac,Concurrency,F#,Hopac,实现该协议需要两个双向通道,这似乎有些奇怪。难道我们不能只使用一个通道,并改变服务器循环,以提供和接受该通道吗。请注意,这在Hopac中是允许的,不会造成任何问题。作业无法在单个同步操作中使用通道向自身发送消息。解释如果只有一个通道而不是单独的getCh和putCh通道,会出现什么问题。提示:考虑有多个客户端的情况。 以上内容来自 是否真的期望新用户在这段旅程中理解库实现的更细微之处?我更喜欢文档给出答案而不是提出问题。为什么对take和get使用单一通道是个坏主意 module HopacEx

实现该协议需要两个双向通道,这似乎有些奇怪。难道我们不能只使用一个通道,并改变服务器循环,以提供和接受该通道吗。请注意,这在Hopac中是允许的,不会造成任何问题。作业无法在单个同步操作中使用通道向自身发送消息。解释如果只有一个通道而不是单独的getCh和putCh通道,会出现什么问题。提示:考虑有多个客户端的情况。

以上内容来自

是否真的期望新用户在这段旅程中理解库实现的更细微之处?我更喜欢文档给出答案而不是提出问题。为什么对
take
get
使用单一通道是个坏主意

module HopacExample

open System
open Hopac
open Hopac.Infixes

type Cell<'a> = {
    takeCh : Ch<'a>
    putCh : Ch<'a>
    }

let get c = Ch.take c.takeCh
let put c (x: 'a) = Ch.give c.putCh x

let cell x = Job.delay <| fun () ->
    let c = {takeCh = Ch (); putCh = Ch ()}
    let server x = 
        Alt.choose [
            Ch.take c.putCh
            Ch.give c.takeCh x ^->. x]

    Job.iterateServer x server >>-. c

run <| job {
    let! c = cell 1
    let print () = Job.start (get c >>- fun i -> printf "%i\n" i)
    let put i = Job.start (put c i)
    do! print()
    do! put 2
    do! print()
    do! put 3
    do! print()
    do! put 4
    do! print()
    do! put 5
    do! print()
    do! put 6
    do! print()
    }

Console.ReadKey()

虽然存在一些差异,但我不会将其归因于异常的并发性。

之所以需要两个通道,是为了强制用户通过服务器。如果您完全删除了服务器,您将能够知道仅使用一个通道的问题是什么。只有一个通道,客户端就可以绕过服务器,直接相互通信

module HopacExample2

open System
open Hopac
open Hopac.Infixes

let get c = Ch.take c
let put c (x: 'a) = Ch.give c x

let cell x = 
    let c = Ch ()
    Job.start (put c x) >>-. c

run <| job {
    let! c = cell 1
    let print () = Job.start (get c >>- fun i -> printf "%i\n" i)
    let put i = Job.start (put c i)
    for i=2 to 6 do
        do! print()
        do! put i
    }

Console.ReadKey()
模块希望示例2
开放系统
开放式霍帕克
开Hopac.中缀
让我们得到c=Ch
设c(x:'a)=Ch,给出cx
设单元格x=
设c=Ch()
Job.start(放置Cx)>>>-。C
运行>-fun i->printf“%i\n”i)
让put i=Job.start(put c i)
对于i=2到6 do
做打印()
做放我
}
Console.ReadKey()

您需要两个频道的原因是为了强制用户通过服务器。如果您完全删除了服务器,您将能够知道仅使用一个通道的问题是什么。只有一个通道,客户端就可以绕过服务器,直接相互通信

module HopacExample2

open System
open Hopac
open Hopac.Infixes

let get c = Ch.take c
let put c (x: 'a) = Ch.give c x

let cell x = 
    let c = Ch ()
    Job.start (put c x) >>-. c

run <| job {
    let! c = cell 1
    let print () = Job.start (get c >>- fun i -> printf "%i\n" i)
    let put i = Job.start (put c i)
    for i=2 to 6 do
        do! print()
        do! put i
    }

Console.ReadKey()
模块希望示例2
开放系统
开放式霍帕克
开Hopac.中缀
让我们得到c=Ch
设c(x:'a)=Ch,给出cx
设单元格x=
设c=Ch()
Job.start(放置Cx)>>>-。C
运行>-fun i->printf“%i\n”i)
让put i=Job.start(put c i)
对于i=2到6 do
做打印()
做放我
}
Console.ReadKey()
5
5
5
5
5
6
module HopacExample2

open System
open Hopac
open Hopac.Infixes

let get c = Ch.take c
let put c (x: 'a) = Ch.give c x

let cell x = 
    let c = Ch ()
    Job.start (put c x) >>-. c

run <| job {
    let! c = cell 1
    let print () = Job.start (get c >>- fun i -> printf "%i\n" i)
    let put i = Job.start (put c i)
    for i=2 to 6 do
        do! print()
        do! put i
    }

Console.ReadKey()