代码之家  ›  专栏  ›  技术社区  ›  Nigel Thorne

如何编写没有可变状态的多客户端服务器?

  •  6
  • Nigel Thorne  · 技术社区  · 16 年前

    我在看函数式编程,有一点很难理解。。在没有可变状态的情况下如何执行以下操作?

    假设我有一个服务器。。客户尝试连接。。每个客户机给服务器一个数字,并告诉服务器当前的总数。

    但是。。客户端如何找到服务器?必须有人保留当前服务器实例。。所以它们有一个可变变量'server'。

    不管我做什么。。我总是得到一个可变的变量,范围越大。

    3 回复  |  直到 16 年前
        1
  •  5
  •   sepp2k    16 年前

    您描述的场景可以这样实现(伪代码):

    let keepTrackOfTotal(total) =
        let conn = waitForConnection()
        let x = readIntFrom(conn)
        let newTotal = total + x
        writeIntTo(conn, newTotal)
        keepTrackOfTotal(newTotal)
    
    let main() = keepTrackOfTotal(0)
    

    在这里,我们使用递归来获得一个无限循环,它跟踪总循环,没有可变变量。

        2
  •  3
  •   Jon Smock    16 年前

    至少在Erlang中,进程本身有一个名称。

    因此,当服务器循环不断地启动自己的新版本(通过在调用结束时调用相同的函数,如sepp2k的优秀伪代码)并将sum作为参数输入时,您的所有客户机都会按名称联系该进程,这样他们仍然可以找到它。

        3
  •  0
  •   Andrew    16 年前

    类似的东西(C++)。 我们有静态指针服务器,服务器对象的每个实例都是不可变的

    #include <pthread.h>
    #include <iostream>
    #include <stdlib.h>
    #include <memory>
    
    pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
    
    class Server
    {
    public:
        Server(int n) : m_n(n){}
        static void Add(int n)
        {        
            pthread_mutex_lock( &mutex1 );
            std::auto_ptr<const Server> srv(getInstance());
            server = new Server(srv->m_n + n);
            pthread_mutex_unlock( &mutex1 );
        }
        static int GetTotal()
        {
            std::auto_ptr<const Server> srv(getInstance());
            return srv->m_n;
        }
    
    private:
    
        static const Server* getInstance()
        {
            if (server == NULL)
                server = new Server(0);
    
            return new Server(server->m_n);
        }
        static volatile const Server* server;
        int const m_n;
    };
    volatile const Server* Server::server = NULL;
    

    每次调用getInstance()都会返回不可变的服务器对象。

    推荐文章