libasync icon indicating copy to clipboard operation
libasync copied to clipboard

How to use multiple threads

Open donglei opened this issue 10 years ago • 4 comments

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;

donglei avatar Jul 15 '15 09:07 donglei

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?

etcimon avatar Jul 15 '15 13:07 etcimon

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.

donglei avatar Jul 16 '15 05:07 donglei

If you are using Linux, you can run the same AsyncTCPListener from multiple threads and the requests will be distributed round robin

etcimon avatar Jul 16 '15 12:07 etcimon

@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 :)

yannick avatar Jun 03 '16 07:06 yannick