不允许使用可变线程局部数据的别名

Dan*_*Dan 5 concurrency multithreading alias d

我是D的新手,我正在编写一个简单的多线程服务器进行练习.在C中启动客户端处理程序线程的一个常见范例是将新的accept()ed套接字的文件描述符传递给pthread_create(),但是D的std.concurrency.spawn()将不允许我传递Socket,因为它是可变的并且可以通过两个线程访问

当然,我实际上并不想要一个不可变的套接字(这就是为什么我真的不想把它放在主线程中,除非我必须) - 我想传递一个可变的套接字并让它超出范围在主线程中.我该怎么做?我应该(/可以)tid.send(s)让线程使用套接字吗?出于某种原因,这对我来说似乎非常笨拙.

我的代码现在:

void main() {
    Socket listener = new TcpSocket;
    ...
    for (;;) {
        Socket s = listener.accept();
        scope(exit) s.close();

        auto tid = spawn(&clientHandler, s);
    }
}

void clientHandler(Socket s) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

产生:错误:静态断言"不允许使用可变线程本地数据的别名"....从这里实例化:spawn!(套接字)

rat*_*eak 7

您需要将套接字转换为共享并在clienthandler中再次返回

auto tid = spawn(&clientHandler, cast(shared) s);

void clientHandler(shared Socket s) {
    Socket sock = cast(Socket)s;
    scope(exit)sock.close();
}
Run Code Online (Sandbox Code Playgroud)

这样做的原因是所有局部变量都是隐式线程局部的,除非指定shared,并且只有对共享或不可变的引用可以作为参数传递给spawn(或send),而通过值传递的东西(没有引用和基元的结构)很好

你也应该将close int放在处理程序中,与当前实现一样,套接字可能会在新生成的线程有机会运行之前关闭