亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問板塊 發(fā)新帖
樓主: csumck
打印 上一主題 下一主題

[技術(shù)動(dòng)態(tài)] 今天聽說了騰訊一個(gè)很牛逼的技術(shù), 求問是怎么實(shí)現(xiàn)的 [復(fù)制鏈接]

論壇徽章:
0
41 [報(bào)告]
發(fā)表于 2014-11-12 19:04 |只看該作者
不就是協(xié)程么。

樓上有個(gè)噴lua的請(qǐng)自重,lua是非對(duì)稱協(xié)程,但不代表是阻塞的。

論壇徽章:
9
程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-10-18 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-01 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-02 06:20:00每日論壇發(fā)貼之星
日期:2015-11-02 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-03 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-06 06:20:00數(shù)據(jù)庫(kù)技術(shù)版塊每周發(fā)帖之星
日期:2015-12-02 15:02:47數(shù)據(jù)庫(kù)技術(shù)版塊每日發(fā)帖之星
日期:2015-12-08 06:20:00
42 [報(bào)告]
發(fā)表于 2015-04-30 19:55 |只看該作者
請(qǐng)參考
Async MySQL Queries with C-API
http    jan.kneschke.de/2008/9/9/async-mysql-queries-with-c-api

論壇徽章:
5
獅子座
日期:2013-08-20 10:12:24午馬
日期:2013-11-23 18:04:102015年辭舊歲徽章
日期:2015-03-03 16:54:152015亞冠之德黑蘭石油
日期:2015-06-29 18:11:1115-16賽季CBA聯(lián)賽之新疆
日期:2024-02-21 10:00:53
43 [報(bào)告]
發(fā)表于 2015-05-12 02:13 |只看該作者
回復(fù) 30# Fixend


    怎么會(huì)呢?Lua的協(xié)程是異常強(qiáng)大的,我就舉個(gè)簡(jiǎn)單的例子,假設(shè)你想遞歸地訪問一個(gè)表,通常的寫法是這樣的:

  1. local function trace(t, f)
  2.    for i, v in ipairs(t) do
  3.       if type(v) == "table" then
  4.          trace(v, f)
  5.       else
  6.          f(v)
  7.       end
  8.    end
  9. end

  10. trace({1,2,3,{4,5,{6,7,8}},9,{10}}, print)
復(fù)制代碼
可是,如果你打算一次取一個(gè)值,去做一些很復(fù)雜的操作(特別的,會(huì)涉及到上下文的操作),比如說,求一下這些值的和,比較簡(jiǎn)單的做法就是閉包加upvalue:

  1. local count = 0
  2. trace({......}, function() count = count + 1 end)
復(fù)制代碼
問題是,如果我這里的處理流程就要求我,這個(gè)地方能一個(gè)一個(gè)地取值怎么辦?

C/C++的辦法是寫一個(gè)迭代器,自己模擬棧,這很麻煩,而且需要技巧,但是Lua里面簡(jiǎn)單到爆了:

  1. local iter = coroutine.wrap(function(t) trace(t, coroutine.yield) end)
  2. for v in iter,t do
  3.    print(v)
  4. end
復(fù)制代碼
其實(shí)非常簡(jiǎn)單,coroutine.wrap將一個(gè)函數(shù)轉(zhuǎn)換成協(xié)程,每次調(diào)用都會(huì)resume,而回調(diào)只需要簡(jiǎn)單地設(shè)置為yield即可。

這就是協(xié)程改變操作流程的強(qiáng)大所在,它能在用代碼表示的,復(fù)雜的操作流程中插入tag,然后在其他地方去監(jiān)聽這些tag,從而把一個(gè)復(fù)雜的遞歸過程變成線性的。

實(shí)際的應(yīng)用,可以考慮看看我的一個(gè)Lua擴(kuò)展模塊,luasched:https://github.com/starwing/luasched

論壇徽章:
5
獅子座
日期:2013-08-20 10:12:24午馬
日期:2013-11-23 18:04:102015年辭舊歲徽章
日期:2015-03-03 16:54:152015亞冠之德黑蘭石油
日期:2015-06-29 18:11:1115-16賽季CBA聯(lián)賽之新疆
日期:2024-02-21 10:00:53
44 [報(bào)告]
發(fā)表于 2015-05-12 02:19 |只看該作者
回復(fù) 28# cokeboL


    擦,上面的帖子是回復(fù)你的,我回復(fù)錯(cuò)人了。

恩,不管了,既然回錯(cuò)了,我就順便舉個(gè)例子吧。比如說,回調(diào)模式,我想買五個(gè)道具:

function buy(item, callback) ... end

怎么辦?

  1. local function buy_times(n)
  2.   buy(item, function()
  3.     if n > 1 then
  4.         buy_times(n-1)
  5.     end
  6.   end)
  7. end
復(fù)制代碼
一個(gè)超級(jí)簡(jiǎn)單的需求就這樣成了遞歸函數(shù)了= =
那么,如果用協(xié)程呢?

假設(shè)我有個(gè)函數(shù)叫buyCO,他不是接受回調(diào),而是在內(nèi)部yield,那么我大可以這么寫:

  1. task.new(function(n)
  2.    for i = 1, n do
  3.       buyCO(item)
  4.    end
  5. end)
復(fù)制代碼
就這樣就可以了,task會(huì)保證這個(gè)函數(shù)會(huì)在“適當(dāng)?shù)臅r(shí)候”執(zhí)行。簡(jiǎn)單吧?

論壇徽章:
36
子鼠
日期:2013-08-28 22:23:29黃金圣斗士
日期:2015-12-01 11:37:51程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-12-14 06:20:00CU十四周年紀(jì)念徽章
日期:2015-12-22 16:50:40IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-01-25 06:20:0015-16賽季CBA聯(lián)賽之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16賽季CBA聯(lián)賽之福建
日期:2016-04-07 11:25:2215-16賽季CBA聯(lián)賽之青島
日期:2016-04-29 18:02:5915-16賽季CBA聯(lián)賽之北控
日期:2016-06-20 17:38:50技術(shù)圖書徽章
日期:2016-07-19 13:54:03程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-21 06:20:00
45 [報(bào)告]
發(fā)表于 2015-05-12 09:11 |只看該作者
回復(fù) 44# starwing83
  1. local iter = coroutine.wrap(function(t) trace(t, coroutine.yield) end)
  2. for v in iter,tab do
  3.    print(v)
  4. end

  5. trace(tab, function(v)
  6.         print(v)
  7. end)
復(fù)制代碼
這兩種寫法,我個(gè)人覺得下面的更簡(jiǎn)潔,邏輯也比較直接,trace內(nèi)部也是一個(gè)一個(gè)callback
用coroutine多寫了點(diǎn)看上去很屌的代碼,但看上去未必直接,關(guān)鍵是,yield給其他地方再回來,跟回調(diào)去調(diào)用別個(gè)再回來沒本質(zhì)區(qū)別,
而且單線程的,并沒有帶來異步的好處,回調(diào)反倒可以在c/c++層做異步的事情來提高效率

論壇徽章:
36
子鼠
日期:2013-08-28 22:23:29黃金圣斗士
日期:2015-12-01 11:37:51程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-12-14 06:20:00CU十四周年紀(jì)念徽章
日期:2015-12-22 16:50:40IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-01-25 06:20:0015-16賽季CBA聯(lián)賽之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16賽季CBA聯(lián)賽之福建
日期:2016-04-07 11:25:2215-16賽季CBA聯(lián)賽之青島
日期:2016-04-29 18:02:5915-16賽季CBA聯(lián)賽之北控
日期:2016-06-20 17:38:50技術(shù)圖書徽章
日期:2016-07-19 13:54:03程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-21 06:20:00
46 [報(bào)告]
發(fā)表于 2015-05-12 09:13 |只看該作者
回復(fù) 41# xphh2008


    我說阻塞的意思是,lua為單線程,yield之后其實(shí)跟調(diào)用其他函數(shù)等調(diào)用完再回來沒本質(zhì)區(qū)別,都是上廁所排隊(duì),沒有帶來異步的好處,參考樓上帖

論壇徽章:
15
射手座
日期:2014-11-29 19:22:4915-16賽季CBA聯(lián)賽之青島
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16賽季CBA聯(lián)賽之四川
日期:2017-02-07 21:08:572015年亞冠紀(jì)念徽章
日期:2015-11-06 12:31:58每日論壇發(fā)貼之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-04 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-07-12 22:20:002015亞冠之浦和紅鉆
日期:2015-07-08 10:10:132015亞冠之大阪鋼巴
日期:2015-06-29 11:21:122015亞冠之廣州恒大
日期:2015-05-22 21:55:412015年亞洲杯之伊朗
日期:2015-04-10 16:28:25
47 [報(bào)告]
發(fā)表于 2015-05-12 16:35 |只看該作者
本帖最后由 yulihua49 于 2015-05-12 16:39 編輯
cokeboL 發(fā)表于 2015-05-12 09:13
回復(fù) 41# xphh2008

如果是單線程,是否yield之后,線程可以給別的客戶端服務(wù)了?
如果是在多客戶端的服務(wù)器里。

沒弄明白,lua是怎么設(shè)定resume的條件的?

在C里邊,都是在yield之前先準(zhǔn)備好resume的條件。

論壇徽章:
36
子鼠
日期:2013-08-28 22:23:29黃金圣斗士
日期:2015-12-01 11:37:51程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-12-14 06:20:00CU十四周年紀(jì)念徽章
日期:2015-12-22 16:50:40IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-01-25 06:20:0015-16賽季CBA聯(lián)賽之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16賽季CBA聯(lián)賽之福建
日期:2016-04-07 11:25:2215-16賽季CBA聯(lián)賽之青島
日期:2016-04-29 18:02:5915-16賽季CBA聯(lián)賽之北控
日期:2016-06-20 17:38:50技術(shù)圖書徽章
日期:2016-07-19 13:54:03程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-21 06:20:00
48 [報(bào)告]
發(fā)表于 2015-05-12 17:12 |只看該作者
回復(fù) 47# yulihua49


    不知道。。。最初開始學(xué)lua看到協(xié)程的時(shí)候,我就個(gè)人判定lua的協(xié)程是個(gè)雞肋的東西,再?zèng)]深入研究

   

論壇徽章:
44
15-16賽季CBA聯(lián)賽之浙江
日期:2021-10-11 02:03:59程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-07-02 06:20:0015-16賽季CBA聯(lián)賽之新疆
日期:2016-04-25 10:55:452016科比退役紀(jì)念章
日期:2016-04-23 00:51:2315-16賽季CBA聯(lián)賽之山東
日期:2016-04-17 12:00:2815-16賽季CBA聯(lián)賽之福建
日期:2016-04-12 15:21:2915-16賽季CBA聯(lián)賽之遼寧
日期:2016-03-24 21:38:2715-16賽季CBA聯(lián)賽之福建
日期:2016-03-18 12:13:4015-16賽季CBA聯(lián)賽之佛山
日期:2016-02-05 00:55:2015-16賽季CBA聯(lián)賽之佛山
日期:2016-02-04 21:11:3615-16賽季CBA聯(lián)賽之天津
日期:2016-11-02 00:33:1215-16賽季CBA聯(lián)賽之浙江
日期:2017-01-13 01:31:49
49 [報(bào)告]
發(fā)表于 2015-05-12 18:58 |只看該作者
回復(fù) 47# yulihua49

就是那個(gè)iter,coroutine寫iter是yield,外面讀iter是resume

論壇徽章:
36
子鼠
日期:2013-08-28 22:23:29黃金圣斗士
日期:2015-12-01 11:37:51程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-12-14 06:20:00CU十四周年紀(jì)念徽章
日期:2015-12-22 16:50:40IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-01-25 06:20:0015-16賽季CBA聯(lián)賽之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16賽季CBA聯(lián)賽之福建
日期:2016-04-07 11:25:2215-16賽季CBA聯(lián)賽之青島
日期:2016-04-29 18:02:5915-16賽季CBA聯(lián)賽之北控
日期:2016-06-20 17:38:50技術(shù)圖書徽章
日期:2016-07-19 13:54:03程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-08-21 06:20:00
50 [報(bào)告]
發(fā)表于 2015-05-12 22:24 |只看該作者
回復(fù) 47# yulihua49


golang這種語言級(jí)實(shí)現(xiàn)的并發(fā)協(xié)程才好用,不需要去做任務(wù)線程、隊(duì)列、回調(diào)之類的

傳統(tǒng)的進(jìn)程池、線程池調(diào)度開銷大,goroutine開銷小得多,就可以搞成池,比如
每個(gè)連接一個(gè)goroutine,然后1對(duì)1的的處理,可以寫線性代碼了

隨便搜了兩段:

  1. //server.go

  2. package main

  3. import (
  4.         "fmt"
  5.         "net"
  6. )

  7. const (
  8.         //綁定IP地址
  9.         ip = "127.0.0.1"
  10.         //綁定端口號(hào)
  11.         port = 3333
  12. )

  13. func main() {
  14.         listen, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP(ip), port, ""})
  15.         if err != nil {
  16.                 fmt.Println("監(jiān)聽端口失敗:", err.Error())
  17.                 return
  18.         }
  19.         fmt.Println("已初始化連接,等待客戶端連接...")
  20.         Server(listen)
  21. }

  22. func Server(listen *net.TCPListener) {
  23.         for {
  24.                 conn, err := listen.AcceptTCP()
  25.                 if err != nil {
  26.                         fmt.Println("接受客戶端連接異常:", err.Error())
  27.                         continue
  28.                 }
  29.                 fmt.Println("客戶端連接來自:", conn.RemoteAddr().String())
  30.                 defer conn.Close()
  31.                 go func() {
  32.                         data := make([]byte, 10)
  33.                         for {
  34.                                 i, err := conn.Read(data)
  35.                                 fmt.Println("客戶端發(fā)來數(shù)據(jù):", string(data[0:i]))
  36.                                 if err != nil {
  37.                                         fmt.Println("讀取客戶端數(shù)據(jù)錯(cuò)誤:", err.Error())
  38.                                         break
  39.                                 }
  40.                                 if string(data[:i]) == "exit" {
  41.                                         conn.Write([]byte{'e', 'x', 'i', 't'})
  42.                                         conn.Close()
  43.                                         break
  44.                                 }
  45.                                 conn.Write(data[0:i])
  46.                         }
  47.                 }()
  48.         }
  49. }
復(fù)制代碼
  1. //client.go

  2. package main

  3. import (
  4.         "fmt"
  5.         "net"
  6. )

  7. const (
  8.         addr = "127.0.0.1:3333"
  9. )

  10. func main() {
  11.         conn, err := net.Dial("tcp", addr)
  12.         if err != nil {
  13.                 fmt.Println("連接服務(wù)端失敗:", err.Error())
  14.                 return
  15.         }
  16.         fmt.Println("已連接服務(wù)器")
  17.         defer conn.Close()
  18.         Client(conn)
  19. }

  20. func Client(conn net.Conn) {
  21.         sms := make([]byte, 1024)
  22.         for {
  23.                 fmt.Print("請(qǐng)輸入要發(fā)送的消息:")
  24.                 _, err := fmt.Scan(&sms)
  25.                 if err != nil {
  26.                         fmt.Println("數(shù)據(jù)輸入異常:", err.Error())
  27.                 }
  28.                 conn.Write(sms)
  29.                 buf := make([]byte, 1024)
  30.                 c, err := conn.Read(buf)
  31.                 if err != nil {
  32.                         fmt.Println("讀取服務(wù)器數(shù)據(jù)異常:", err.Error())
  33.                 }
  34.                 fmt.Println(string(buf[0:c]))
  35.         }

  36. }
復(fù)制代碼
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP