成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

x(z).z<a>.0 | x<w>.y<w>.0 | y(v)

Tony_Zby / 830人閱讀

摘要:過程是一個計算單元,計算是通過通訊來完成的。標(biāo)題的表達(dá)式里還有一個符號,表示一個無行為的過程。一個過程的是它和外部產(chǎn)生行為交互的唯一方式。所以如果兩個過程需要通過一個交互,這個必須在兩個過程中都是,其中一方用于發(fā)送,另一方用于接收。

這篇文章的標(biāo)題是一個π表達(dá)式,結(jié)尾是一段JavaScript代碼,和這個表達(dá)式的含義完全一致,或者說,完成了這個表達(dá)式的估值。

π演算(π calculus)是一種表達(dá)并發(fā)過程(process)的數(shù)學(xué)語言,和λ在形式上有很多類似之處;λ已經(jīng)是公認(rèn)的計算模型,它和圖靈機(jī)或遞歸理論(Recursion Theory)描述的計算模型是等價的,但是這個計算模型無法描述并發(fā)計算。

π沒有λ那樣的地位;它只是描述并發(fā)計算的模型之一,在計算數(shù)學(xué)領(lǐng)域科學(xué)家們還沒有對并發(fā)計算模型達(dá)成一致,每一種并發(fā)計算模型都強(qiáng)調(diào)了并發(fā)計算的某些方面的特性但還沒有一個模型成為λ那樣的經(jīng)典模型可以解釋其他所有模型,或者證明其等價性;數(shù)學(xué)家們選擇使用不同的模型研究他們感興趣的并發(fā)計算特性。

π是并發(fā)計算模型中最精簡的一個,具有最小的概念元素集;它只包含兩個概念:過程(process)和通訊(channel)。過程是一個計算單元,計算是通過通訊來完成的。

“計算是通過通訊完成的”對于不熟悉數(shù)學(xué)理論的人來說不容易理解;這里也沒有更好的解釋;推薦看一點關(guān)于λ的介紹,感受一下計算是如何通過變量名binding和替換(substitution)完成的。 

在數(shù)學(xué)上,λ可以被encode在π里,但是不該對encode一詞產(chǎn)生基于其自然語言含義的聯(lián)想,如果想了解它的確切含義,請系統(tǒng)學(xué)習(xí)λ和π的相關(guān)理論。

題目是一個π表達(dá)式,也可以看作是用π演算寫下的一段程序,即把π當(dāng)作一種編程語言,雖然這個表達(dá)式?jīng)]有什么實際用處,也沒有人會打算用π作為編程語言寫下實際的程序;但是在對照了題目的π表達(dá)式和文中的JavaScript代碼之后,我相信你會獲得一些新感受,關(guān)于對并發(fā)的理解,什么是描述并發(fā)的最小概念集。

這篇文章是一個起點,如果我有時間,還會逐步解釋在JavaScript里的callback,emitter,promise,async/await,等等,都不是在并發(fā)計算模型意義上的最小概念,它們更多的考慮了實際使用中最常用需求、最簡潔書寫、最容易學(xué)習(xí)等工程特性或需求,但同時也會遇到一些棘手的問題;而這篇文章,就是在探索對并發(fā)編程而言,最原始(primitive)的東西是什么。

解釋表達(dá)式

和λ一樣簡單的是,在π里只有name,name表示一個channel。

標(biāo)題里的π表達(dá)式(π-term)沒有包含所有的π符號,只包含了其中的一部分;解釋如下:

x(z)的意思是從channel x接收到z

z的意思是向channel z發(fā)送a

x(z)和z都稱為π前綴(prefix),分別是input prefix和output prefix,是π里最重要的兩個前綴;

"."(dot)可以被理解為繼續(xù)(continuation),或者反過來理解,阻塞(blocking);它的意思是前綴必須先完成通訊,即接收或發(fā)送完成,"."之后的表達(dá)式才可以開始執(zhí)行,或者稱為估值;這是π里唯一表達(dá)順序(order)的地方;

你可以給一個表達(dá)式取一個名字,習(xí)慣上使用大寫字母P, Q, R...

例如:

如果 P = z.0,最左側(cè)的表達(dá)式就可以寫成x(z).P;

如果 P = x(z).z.0,則最左側(cè)的表達(dá)式就可以寫成P;

如果

P = x(z).z.0

Q = x.y.0

R = y(v).v(u).0

則整個標(biāo)題的表達(dá)式可以寫成 P | Q | R

有時候我們采用π.P的寫法表示一個通用的π表達(dá)式,而不關(guān)心這個表達(dá)式里的π具體是那種前綴;

當(dāng)然也可以定義: U = P | Q | R,它仍然是π表達(dá)式。

每個π表達(dá)式都表達(dá)了一個過程。

"|"(vertical pipe)在π里的含義是并發(fā)組合,可以看作過程的運(yùn)算符;U = P | Q | R就可以理解為過程U是由三個過程并發(fā)組成的。

π里的另一個組合過程的運(yùn)算符是"+",summation,我們暫不介紹。

標(biāo)題的表達(dá)式里還有一個符號00表示一個無行為的過程(inaction)。

Free name

這一段可以在看了后面的代碼之后再回來對照理解。

Free name的含義和λ或編程語言里的定義一致;它是bound name的反義詞;bind的意思和λ也是一致的(λx);

在π里有兩個符號會bind name,標(biāo)題里的表達(dá)式只出現(xiàn)了一個,即輸入前綴,例如:x(z)。這很容易理解,在JavaScript代碼里我們常用listener函數(shù)接收消息:

emitter.on("data", data => {
    // do something with data
})

這里的data變量的scope就是在這個匿名函數(shù)內(nèi)的,即bound name。一個過程P的Free name是它和外部產(chǎn)生行為交互的唯一方式。

這里是π process教材里的描述:

The free names of a process circumscribe its capabilities for action: for a name x, in order for P to send x, to send via x, or to receive via x, it must be that x ∈ fn(P). Thus in order for two processes to interact via a name, that name must occur free in both of them, in one case expressing a capability to send, and in the other a capability to receive.

from π calculus by Davide Sangiorgi and David Walker

譯:

一個過程的free name決定了它的行為能力,對于過程P中的name x,如果P能夠:

發(fā)送x

通過x發(fā)送其他name

通過x接收其他name

x必須是P的free name。所以如果兩個過程需要通過一個name交互,這個name必須在兩個過程中都是free name,其中一方用于發(fā)送,另一方用于接收。

Reduction

這個詞在編程界被用爛了。但是它的含義沒有什么高大上的地方。一個數(shù)學(xué)公式的形式變換就是reduction,當(dāng)然我們正常情況下是希望它越變越簡潔的(所以叫reduce),除了你的陰險的數(shù)學(xué)老師會在出題時有個相反的邪惡目的。

π只有一個reduction:

x.P | x(z).Q -> P | Q[y/z]

含義是y從channel x發(fā)送出去之后,P才可以繼續(xù)執(zhí)行;同時x(z)前綴收到了y,Q得以繼續(xù)執(zhí)行,此時Q里的所有z都要替換成y。

在編程中:

x(z).Q意味著如果x尚未收到數(shù)據(jù),Q不能開始執(zhí)行;這個input prefix在程序語言里很容易實現(xiàn),就是常見的listener或者callback。

x.P意味著只有y被讀走,P才會開始執(zhí)行;這類似lazy實現(xiàn)的stream,在數(shù)據(jù)沒有被讀走之前,不會再向buffer填充數(shù)據(jù);在編程語言里實現(xiàn)這個表達(dá)式,和實現(xiàn)readable stream時,收到drain事件才開始填充數(shù)據(jù)類似。

代碼

我們先假定存在一個構(gòu)造函數(shù)或工廠方法,可以構(gòu)造一個channel對象;我們先不回答channel如何構(gòu)造,以及它內(nèi)部是什么。

我們要求channel對象有一對接口方法,按照π的邏輯應(yīng)該叫做send和receive;

注意在π里我們沒有類型和值的概念,一切變量皆channel,寫成代碼就是一切變量皆channel對象,通過channel傳遞的變量也是channel,這是π系統(tǒng)的重要特性之一:pass channel via channel(因為它會讓name突破一個scope使用)。

我們首先發(fā)現(xiàn)這個表達(dá)式里的free name都得先聲明(why?);x,y,w,a都聲明成channel(a在這個例子中沒有實際用于通訊,可以是任何東西)。

第一段代碼就是這個樣子。

class Channel {
    // placeholder
}

const channel = () => new Channel()

const x = channel()
const y = channel()
const w = channel()
const a = channel()

"."(dot)所表達(dá)的繼續(xù),我們可以用調(diào)用一個函數(shù)來實現(xiàn);.0,可以用調(diào)用空函數(shù)(() => {})表示;

第一個表達(dá)式:x(z).z.0,可以這樣寫:

x.receive(z => z.send(a, () => {}))

receive方法形式上是提供一個函數(shù)f作為參數(shù),channel x在接收到值z的時候調(diào)用這個函數(shù)f(z);

第二個表達(dá)式:x.y.0,可以這樣寫:

x.send(w, () => y.send(w, () => {}))

注意這里要send成功之后才能繼續(xù)而不是調(diào)用send后就繼續(xù),所以不能寫成:

x.send(w)
y.send(w)

最后一個表達(dá)式:y(v).v(u).0

y.receive(v => v.receive(u => (() => {})()))

到這里我們寫完了使用者代碼;在使用的時候我們也給Channel類的接口下了定義;如果你問哪個表示并發(fā)的vertical pipe(|)哪里去了?你想一下,我在文章的最后給出問題的答案。

在實現(xiàn)Channel類之前我們還要考慮一個順序問題。

π里的reduction是兩個并發(fā)過程之間發(fā)生的;在reduction的時候我們要調(diào)用兩個函數(shù)實現(xiàn)"."表示的繼續(xù),分別是發(fā)送者繼續(xù)和接收者繼續(xù),我們是否應(yīng)該約定一個固定的順序?

答案是不應(yīng)該;對于這里寫下的玩具代碼我們甚至故意加入了隨機(jī)性,這才是并發(fā)的含義,并發(fā)過程之間木有固定執(zhí)行順序。

我們先定義一個reduce函數(shù);它的前提是send和receive兩個方法都被調(diào)用過了;這里存在兩種順序可能性:如果receive先被調(diào)用了,f被保存下來直到send被調(diào)用,這和常見的listener沒有區(qū)別;但π也允許反過來的順序,send先被調(diào)用了,則c和f都被保存下來,等到receive調(diào)用的時候再使用,這就是π里的兩個前綴會block后面的表達(dá)式估值的實現(xiàn)。

無論send和receive的實際調(diào)用順序如何,我們都希望reduce可以隨機(jī)執(zhí)行sender和receiver提供的回調(diào)函數(shù)。

class Channel {
    reduce () {
        if (!this.sendF || !this.receiveF) return
        let rnd = Match.random()
        if (rnd >= 0.5) {
            this.sendF()
            this.receiveF(this.c)
        } else {
            this.receiveF(this.c)
            this.sendF()
        }
    }

    send (c, f) {
        this.c = c
        this.sendF = f
        this.reduce()
    }

    receive (f) {
        this.receiveF = f
        this.reduce()
    }
}

寫出reduce之后send和receive就是無腦代碼了;在標(biāo)題的表達(dá)式里每個channel都只用了一次,所以我們不用在這里糾結(jié)如果重復(fù)發(fā)送和接受的情況如何解決;各種參數(shù)檢查和錯誤處理也先不管了,先跑起來試試。

最后所有的代碼都在這里,加了一點打印信息,你可以運(yùn)行起來感受一下,也思考一下:

π系統(tǒng)capture了并發(fā)編程里哪些最重要的特性?沒有capture下來哪些?這段代碼里有什么東西是可能在實際編程問題上可以派上用場?

callback,emitter,promise,async/await能用Channel表達(dá)或者實現(xiàn)嗎?如果能,大概會是什么樣?

rx和這個Channel有什么異同?

class Channel {
  constructor (name) {
    this.name = name
  }

  reduce () {
    if (!this.sendF || !this.receiveF) return
    console.log(`passing name ${this.c.name} via channel ${this.name}`)
    let rnd = Math.random()
    if (rnd >= 0.5) {
        this.sendF()
        this.receiveF(this.c)
    } else {
        this.receiveF(this.c)
        this.sendF()
    }
  }

  send (c, f) {
    console.log(`${this.name} sending ${c.name}`)
    this.c = c
    this.sendF = f
    this.reduce()
  }

  receive (f) {
    console.log(`${this.name} receiving`)
    this.receiveF = f
    this.reduce()
  }
}

const channel = name => new Channel(name)
const x = channel("x")
const y = channel("y")
const w = channel("w")
const a = channel("a")

x.receive(z => z.send(a, () => console.log("term 1 over")))
x.send(w, () => y.send(w, () => console.log("term 2 over")))
y.receive(v => v.receive(u => (() =>
  console.log(`term 3 over, received ${u.name} finally`))()))
答案

為什么vertical pipe表示的并發(fā)組合沒了呢?因為連續(xù)執(zhí)行上面代碼段里最后三句的時候,就是并發(fā)了;一定要說語言上什么符號對應(yīng)了"|"的話,對于JavaScript就是;號了;它本來在語言上是statement的順序組合,在我們這個代碼里,就是并發(fā)組合了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106973.html

相關(guān)文章

  • Python完成1個全連接層的神經(jīng)元網(wǎng)絡(luò)

      本文關(guān)鍵闡述了Python完成1個全連接層的神經(jīng)元網(wǎng)絡(luò),文章內(nèi)容緊扣主題進(jìn)行詳盡的基本介紹,具有很強(qiáng)的實用價值,必須的朋友可以學(xué)習(xí)一下  序言  在本文中,提前準(zhǔn)備用Python重新開始完成1個全連接層的神經(jīng)元網(wǎng)絡(luò)。你可能會說,為何需要自己去完成,有許多庫和架構(gòu)能夠給我們做這些事,例如Tensorflow、Pytorch等。這兒只想說僅有自己親自完成了,就是自己的?! ∠肫鸾袢账麖慕佑|到了從事...

    89542767 評論0 收藏0
  • vue項目中canvas實現(xiàn)截圖功能

      在vue項目中canvas實現(xiàn)截圖功能是常用的,下面是具體代碼:  實現(xiàn)效果:  在vue項目中做的一個截圖功能(只能夠截取圖片),只用鼠標(biāo)就可以在畫面中進(jìn)行框選截取?! 崿F(xiàn):做一個彈窗,打開彈窗的時候傳入要截的圖,接下來在這個窗口里面,點擊截圖按鈕,開始截圖;點擊取消按鈕,取消截圖?! 〈翱诶锩娴膆tml主要是三個部分,一個是可截圖區(qū)域,一個是截取圖片的回顯,一個是操作按鈕(截圖按鈕和取消...

    3403771864 評論0 收藏0
  • 怎樣依據(jù)python完成單眼三維成像詳細(xì)說明

      單眼三維成像是依據(jù)單獨監(jiān)控攝像頭健身運(yùn)動仿真模擬雙目視覺獲得物件和空間里的三維視覺信息內(nèi)容,下面本文關(guān)鍵為大家介紹了對于如何依據(jù)python完成單眼三維成像的資料,原文中依據(jù)案例編碼推薦的十分詳盡,必須的小伙伴可以借鑒一下  一、單眼三維成像簡述  客觀現(xiàn)實的物件是三維立體的,而我用監(jiān)控攝像頭獲得的圖象是二維動畫的,但我們可以依據(jù)二維圖像認(rèn)知總體目標(biāo)三維信息內(nèi)容。三維重建技術(shù)要以相對應(yīng)的形式解...

    89542767 評論0 收藏0
  • Python+OpenCV實現(xiàn)圖像識別替換功能詳解,步驟解析

      OpenCV-Python是一個Python庫,旨在解決計算機(jī)視覺問題。那么,很多的小伙伴都有興趣了解一下吧,正好,小編給大家總結(jié)了關(guān)于這方面的一些代碼問題,本文將利用Python+OpenCV實現(xiàn)圖像識別替換功能,小伙伴們在讀完之后,可以自己動手實踐一下哦。   OpenCV-Python是一種Python庫,目的在于處理機(jī)器視覺難題。   OpenCV可以說是開源系統(tǒng)的機(jī)器視覺庫,1999...

    89542767 評論0 收藏0
  • python做圖基本之plt.contour案例詳細(xì)說明

      contour和contourf全是畫三維立體等高線圖的,接下來本文主要是為大家介紹了關(guān)于python做圖基本操作之plt.contour的相關(guān)信息,原文中依據(jù)案例編碼推薦的十分詳盡,需用的小伙伴可以參考一下  序言  plt.contour是python中用以畫等值線的函數(shù)公式,這兒簡單的介紹plt.contour的應(yīng)用?! ?yīng)用示例  importnumpyasnp   importmat...

    89542767 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<