如何在 ctrl+c 发生时优雅地退出 D 程序?
How to exit from a D program gracefully when ctrl+c happens?
我想通过停止事件循环来优雅地关闭 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.
是否有一个简单的库可以做到这一点?
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/Whosebug/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/Whosebug/q1
$
我想通过停止事件循环来优雅地关闭 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.
是否有一个简单的库可以做到这一点?
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/Whosebug/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/Whosebug/q1
$