libasync
libasync copied to clipboard
How to use multiple threads
How to use multiple threads with libasync, could you give an example? Expect to fork some of the working threads when the main thread is started. The jobs will be processed by the working threads;
Hi donglei,
I thought about writing an example for this using AsyncSignal, it should be straightforward but I'm not sure yet what it should cover.
The typical implementation would be triggered by an HTTP request, which is at a much higher level.
// Suggestive, does not actually compile:
////////////////////////////////////////////////////////////////
shared AsyncSignal gs_sigqueue;
__gshared Mutex gs_mtx;
__gshared Variant[] gs_queue;
shared static this() { mtx = new Mutex; }
// Will be called by the event loop from the same thread that ran (AsyncSignal).run(&queueHandler) when (AsyncSignal).trigger() is called from any thread
void queueHandler() {
synchronized(gs_mtx) {
foreach (item; gs_queue)
handleItem(item);
gs_queue.destroy();
}
}
// This is a thread-safe function that will send a task to the worker
void enqueue(MyObj item) {
synchronized(gs_mtx) gs_queue ~= Variant(item);
gs_sigqueue.trigger();
}
void main() {
// The below handler will be handled by the current thread.
// to register workers, create the AsyncSignal from another thread.
// You can use `new Thread(&del)` to create a worker and typically run this function in it.
gs_sigqueue = new shared AsyncSignal(getThreadEventLoop());
gs_sigqueue.run(toDelegate(&queueHandler)); //std.functional
/// runs until the process is killed (with ctrl+c)
while(getThreadEventLoop().loop()) continue;
}
shared static ~this() { destroyAsyncThreads(); } // never forget
In this example, you can call enqueue from any thread and the item will be handled by the main thread. Do you have a specific protocol that should enqueue items?
Thank you for your example. I have a web project written in D, in order to improve the performance and ability to handle, I intend to use multi thread.The main thread only receives the request, distributed it to the working threads.
If you are using Linux, you can run the same AsyncTCPListener from multiple threads and the requests will be distributed round robin
@donglei for your specific need you don't need multi thread, it would be actually bad. Linux can do the connection sharding for you with SO_REUSEPORT ( https://lwn.net/Articles/542629/ ). you do not want to have the synchronization overhead within the web framework as long as the clients do not need to communicate together. thus the solution you are most probably looking for is fairly simple: just compile with libasync and start the binary multiple times. it will "magically" distribute your load :)