February 23, 2016 Starting threads inside class | ||||
---|---|---|---|---|
| ||||
My goal with the code below is to eventually have my main communicate with Foo and Bar classes listening for packets on a different address/port, each in a separate thread. They would then communicate with Foobaz and Barbaz threads respectively to do other work. In trying to get just Foo working though, I'm getting this error: Error: template std.concurrency.spawn cannot deduce function from argument types !()(void delegate(Tid ownerTid), Tid), candidates are: D:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(466): std.concurrency.spawn(F, T...)(F fn, T args) if (isSpawnable!(F, T)) The code works fine if I call daemon as a normal function, but it holds up the main thread. Is there anything I'm doing wrong here? I'm not accessing anything outside this class from inside, and the most I would be doing from outside is accessing the Tid in order to send packets from my main. class Foo { private string address = "127.0.0.1"; private ushort port = 55555; private ubyte[256] buffer; private TcpSocket mysock; Tid listenerd; this() { listenerd = spawn(&daemon, thisTid); } void setup() { mysock = new TcpSocket(); mysock.blocking = true; try { mysock.connect(new InternetAddress(address, port)); } catch (SocketOSException e) { } } void initialise() { // send init packet } void closeConnection() { // send close packet } void packetHandler() { // do something with buffer } void daemon(Tid ownerTid) { setup(); initialise(); int rxSize = -1; while (true) { rxSize = mysock.receive(buffer); if (rxSize == 0) { break; } packetHandler(); } closeConnection(); } } |
February 23, 2016 Re: Starting threads inside class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Josh | On 02/23/2016 07:31 AM, Josh wrote: > My goal with the code below is to eventually have my main communicate > with Foo and Bar classes listening for packets on a different > address/port, each in a separate thread. The main issue is that in D all data is thread-local by-default. main() cannot create objects and then implicitly give access to those objects from other threads. > the most I would be doing from outside is accessing the Tid in order > to send packets from my main. Even that's not needed because spawn() returns the Tid. And you don't need to pass ownerTid, it is already available to child threads. Options: a) spawn() a thread by passing necessary data for it to create a Foo. (Preferred.) b) In case main() needs to have access to the objects, construct objects as shared(Foo) and pass references to threads. Here is the code with option a: import std.socket; import std.concurrency; void daemon() { auto f = new Foo(); f.setup(); f.initialise(); long rxSize = -1; while (true) { rxSize = f.mysock.receive(f.buffer); if (rxSize == 0) { break; } f.packetHandler(); } f.closeConnection(); } class Foo { private string address = "127.0.0.1"; private ushort port = 55555; private ubyte[256] buffer; private TcpSocket mysock; Tid listenerd; void setup() { mysock = new TcpSocket(); mysock.blocking = true; try { mysock.connect(new InternetAddress(address, port)); } catch (SocketOSException e) { } } void initialise() { // send init packet } void closeConnection() { // send close packet } void packetHandler() { // do something with buffer } } void main() { auto listenerd = spawn(&daemon); } Ali |
Copyright © 1999-2021 by the D Language Foundation