代码之家  ›  专栏  ›  技术社区  ›  Istvan

当ctrl+c发生时,如何优雅地退出D程序?

  •  0
  • Istvan  · 技术社区  · 7 年前

    我想通过停止EventLoop优雅地关闭vibe.d应用程序。

    import vibe.vibe;
    import core.sys.posix.signal;
    
    void main()
    {
      enum SIGINT = 2;
      signal(SIGINT, &stopapp);
    
      auto settings = new HTTPServerSettings;
      settings.port = 8080;
      settings.bindAddresses = ["::1", "127.0.0.1"];
      listenHTTP(settings, &hello);
    
      logInfo("Please open http://127.0.0.1:8080/ in your browser.");
      runApplication();
    
    }
    
    void hello(HTTPServerRequest req, HTTPServerResponse res)
    {
      res.writeBody("Hello, World!");
    }
    
    void stopapp(int value){
      logInfo("Stopping app...");
      exitEventLoop();
    }
    

    不幸的是,这不起作用:

    source/app.d(7,9): Error: function core.stdc.signal.signal(int sig, extern (C) void function(int) nothrow @nogc @system func) is not callable using argument types (int, void function(int value))
    source/app.d(7,9):        cannot pass argument & stopapp of type void function(int value) to parameter extern (C) void function(int) nothrow @nogc @system func
    dmd failed with exit code 1.
    

    有没有一个简单的图书馆能做到这一点?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Arun    7 年前

    signal 是C函数。对于C函数调用D函数,D函数应标记为 extern(C) signalHandler() .

    import  std.stdio;
    
    extern(C) void signal(int sig, void function(int) );
    
    // Our handler, callable by C
    extern(C) void handle(int sig) {
        writeln("Signal:",sig);
    }
    
    void main()
    {
        enum SIGINT = 2; // OS-specific
    
        signal(SIGINT,&handle);
        writeln("Hello!");
        readln();
        writeln("End!");
    }
    

    至于vibe.d示例,vibe.d自己处理sigint。这应该有效:

    import vibe.vibe;
    
    void main()
    {
        auto settings = new HTTPServerSettings;
        settings.port = 8080;
        settings.bindAddresses = ["::1", "127.0.0.1"];
        listenHTTP(settings, &hello);
    
        logInfo("Please open http://127.0.0.1:8080/ in your browser.");
        runApplication();
    }
    
    void hello(HTTPServerRequest req, HTTPServerResponse res)
    {
        res.writeBody("Hello, World!");
    }
    

    运行并按下C-C。

    09:21:59 ~/code/d/stackoverflow/q1
    $ ./q1
    [main(----) INF] Listening for requests on http://[::1]:8080/
    [main(----) INF] Listening for requests on http://127.0.0.1:8080/
    [main(----) INF] Please open http://127.0.0.1:8080/ in your browser.
    ^C[main(----) INF] Received signal 2. Shutting down.
    Warning (thread: main): leaking eventcore driver because there are still active handles
    FD 6 (streamListen)
    FD 7 (streamListen)
    Warning (thread: main): leaking eventcore driver because there are still active handles
    FD 6 (streamListen)
    FD 7 (streamListen)
    09:22:04 ~/code/d/stackoverflow/q1
    $