libuv high concurrency asynchronous use

Source of the problem:
When developing libuv client-server, it is necessary to send data to the client concurrently, and libuv will use the uv_write function. Therefore, my initial plan is:
1. Create a thread pool;
2. Allocate data memory from the thread pool buf, and package it;
3. Send the package to uv_write;
4. Release the buf in uv_write_cb;
by opening up 30 threads, it is found that the client can receive data correctly, but cannot call uv_write_cb, resulting in increased memory. Check the official document:
The async thread communication works on loops so although any thread can be the message sender, only threads with libuv loops can be receivers (or rather the loop is the receiver). libuv will invoke the callback (print_progress) with the async watcher whenever it receives a message
.It roughly means that the callback function can only be called by the function inside the ibuv that passes through the loop. The solution that can be used is to send the data to be called in uv_queue_work. After testing, uv_write_cb can respond correctly .
The scheme adopted by the thread pool is:
1. Create your own thread pool self_pool;
2. Group the data packet buf1, and send buf1 to uv_queue_work;
3. The uv_work function of uv_queue_work parses buf1 and sends the data to uv_write;
after testing, it is found that if the self_pool has more than 1 thread, the function will crash, that is to say, the concurrent processing of uv_queue_work will cause program problems and the locking will be invalid.
Improvement plan:
1. Create your own thread pool self_pool;
2. Create a single thread thread;
3. Self_pool group data packet buf1 and add data to queue
4. Thread obtains buf, creates req object and sends data to uv_queue_work
5. uv_queue_work The uv_work function parses buf1 and sends the data to uv_write;
after testing, there is no problem with the above scheme.
Continue to check the documentation and find that uv_async_send can also be used as other external threads to call the interface, but uv_async_t.data is not thread-safe, and if uv_async_t is processed concurrently, the Before the callback function of uv_async_send does not respond, multiple calls may be merged into one, that is to say, only one callback function may respond to N calls.
Solution 1
1. Create the uv_async_t object async and add it to the set;
2. uv_async_init and call uv_async_send; 3.
In the callback function, uv_close((uv_handle_t*) &async, NULL);
set deletes the record.
Scenario 2
1. Create two queues queue1 as an idle queue and queue2 as a busy queue;
2. Create N uv_async_t into queue1;
3. When data needs to be sent, take the idle uv_async_t from the queue and send it asynchronously
4. In the callback function, Put uv_async_t into queue2

Reference:
Message passing between multiple threads of libuv: https://www.cnblogs.com/guoxiaoqian/p/3945242.html
libuv's async uses
https://blog.csdn.net/limite_god/article/details/43700325
based on TCP design of libuvhttp:
//www.cnblogs.com/wqvbjhc/p/3758141.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324516019&siteId=291194637