2009-12-23 73 views
5

在教程: http://www.erlang.org/doc/tutorial/cnode.html二郎Ç節點相關的問題

有下面的例子:


/* cnode_s.c */ 
#include 
#include 
#include 
#include 
#include "erl_interface.h" 
#include "ei.h" 
#define BUFSIZE 1000 
int main(int argc, char **argv) { 
    int port;        /* Listen port number */ 
    int listen;        /* Listen socket */ 
    int fd;         /* fd to Erlang node */ 
    ErlConnect conn;       /* Connection data */ 
    int loop = 1;       /* Loop flag */ 
    int got;         /* Result of receive */ 
    unsigned char buf[BUFSIZE];    /* Buffer for incoming message */ 
    ErlMessage emsg;       /* Incoming message */ 
    ETERM *fromp, *tuplep, *fnp, *argp, *resp; 
    int res; 
    port = atoi(argv[1]); 
    erl_init(NULL, 0); 
    if (erl_connect_init(1, "secretcookie", 0) == -1) 
    erl_err_quit("erl_connect_init"); 
    /* Make a listen socket */ 
    if ((listen = my_listen(port))

我懷疑erl_receive_msg是一個阻塞調用,我不知道該怎麼克服這一點。在C網絡編程中有「select」語句,但在Erlang EI API中我不知道是否有這樣的語句。

基本上我想建立一個C節點,它不斷地發送消息到Erlang節點。爲了簡單起見,假設只有一個Erlang節點。

Erlang節點必須處理它從C節點收到的消息。 Erlang節點不應該確保它已經收到消息,也不需要回復處理結果。所以一旦發送信息,我不關心它的信仰。

有人可能會認爲,人們可以修改代碼:

... 
if (emsg.type == ERL_REG_SEND) { 
    ... 
    while(1) { 
     //generate tuple 
     erl_send(fd, fromp, tuple); 
     //free alloc resources 
    } 
    ... 
} 

這將在我們的生產和消費(發送)消息的無限循環。 但是有一個重要的問題:如果我這樣做,那麼C節點可能會發送太多的消息到Erlang節點(所以應該有一種方法可以將消息從Erlang節點發送到C節點以減慢速度),或者Erlang節點可能認爲C節點已關閉。

我知道,這些問題必須很短的套件(這是漫長的,醜陋的),但總結:

什麼機制(過程調用,算法)一個可能用來開發下一個熱切的製片人在Erlang的懶惰消費者,這樣雙方都知道潛在的上下文?

回答

2

我使用的端口驅動程序我自己的情況下,你正在描述(有沒有觸及C節點,因爲我寧願有更多的解耦)。

查看Erlang的端口驅動程序庫:EPAPI。有一個項目可以利用這個庫:Erland DBus

+0

問題是生產者將成爲C節點,Erlang節點將成爲消費者。我考慮過使用端口的想法,但是在連續循環中調用端口驅動程序的服務似乎並不是實現此目的的最佳方式。 – user237855 2009-12-23 20:29:20

+0

@zalmoxis:有很多不同的方式來解決這種情況,其中之一可能是使用「基於令牌的信用算法」。 「消費者節點」向生產者節點發送「信用」。每個「發送」都需要一個「信用」:當沒有更多信息時,「製片人」必須等待下一個「發送」信用。 – jldupont 2009-12-23 20:32:23

+0

@zalmoxis:上面描述的「基於標記的整形器」可以很容易地在「producer」一側(用C語言編寫)實現,而在Erlang方面增加對該方案的支持同樣微不足道。既然你已經爲「痛苦」使用「C節點」,那麼我知道你可以採用端口驅動。歡呼,玩得開心! (無論如何,一如既往,將我的貢獻視爲您考慮的建議)。 – jldupont 2009-12-23 20:34:38

1

您是否檢查ei_receive_msg_tmo功能?我認爲它的作用類似於Erlang構造之後的接收,所以如果將timeout設置爲0,它將是非阻塞的。

我相信erl_interface已被棄用,應該使用ei來代替。這可能是一個完整的錯誤信息,雖然...

+0

謝謝,我目前正在測試它。請注意,通過使用超時0調用ei_receive_msg_tmo,它將變爲阻塞狀態。 – user237855 2009-12-23 21:01:11

+0

好的。顯然,非超時函數會回到ms = 0的超時函數。這就是ms = 0變爲阻塞的原因(參見 ei_read_t()函數erl_interface/src/misc/ei_portio.c)。我會稱這是對功能的懶惰的勝利:) – Zed 2009-12-23 21:19:27

1

你需要仔細看看你發佈的教程鏈接。 (搜索「最後我們有C節點客戶端的代碼」)。您將看到作者提供了一個客戶端cnode實現。它看起來很合理。