Skip to content
This repository has been archived by the owner on Jun 22, 2021. It is now read-only.

event loop hang on uv_async_t #185

Open
sea5727 opened this issue Jan 24, 2021 · 1 comment
Open

event loop hang on uv_async_t #185

sea5727 opened this issue Jan 24, 2021 · 1 comment

Comments

@sea5727
Copy link

sea5727 commented Jan 24, 2021

I'm newbe libuv.

if It is my fault, please tell me about that ^-^

this is my sample that use uv_timer_t(1000ms) and uv_async_t (10 ~ 10000times)

if a count value is more than abount 1000
eventloop hang( no timer callback me ) and cpu high somtimes

if a count value is more than about 5000
eventloop hang( no timer callback me ) and cpu high always

  • Version: v1.40.0
  • Platform: Linux janus 3.10.0-1127.10.1.el7.x86_64 How to get started? #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

my build command is

$ git clone -b v1.40.0 https://github.com/libuv/libuv.git
$ cd libuv
$ mkdir build
$ cd build
$ cmake ..
$ make -j 4
$ make install

my os information is

$ uname -a
$ Linux janus 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/redhat-release
$ CentOS Linux release 7.8.2003 (Core)

$ ulimit -a
$ open files                      (-n) 65000

build option : c++11

#include <iostream>
#include <thread>
#include <vector>
#include <uv.h>

uv_loop_t* loop;


void
closeCb(
    uv_handle_t * handle){
    free(handle->data);
}


void
asyncCallback2(
    uv_async_t * handle){
    static int count = 0;
    printf("asyncCallback2 i:%d\n", count);
    count += 1;

    uv_close((uv_handle_t *)handle, closeCb);
}


void
timer_cb(uv_timer_t * handle){
    printf("timer_cb call\n");
}


void * thread_f(void *){
    std::this_thread::sleep_for(std::chrono::seconds(1));
    int i = 0;
    int ret;
    for(i = 0 ; i < 1000 ; ++i){ // 10 ~ 10000
        uv_async_t * async = (uv_async_t *)malloc(sizeof(uv_async_t));
        ret = uv_async_init(loop, async, asyncCallback2);
        
        if(ret != 0) {
            printf("uv_async_init ret:%d\n", ret);
            exit(0);
        }
        ret = uv_async_send(async);
        if(ret != 0) {
            printf("uv_async_send ret:%d\n", ret);
            exit(0);
        }
    }

}
int main(int argc, char * argv[]){
    
    loop = uv_loop_new();
    uv_loop_init(loop);

    uv_timer_t * timer = (uv_timer_t *)malloc(sizeof(uv_timer_t));
    uv_timer_init(loop, timer);
    uv_timer_start(timer, timer_cb, 0, 1000);
    
    pthread_t pid;
    pthread_create(&pid, NULL, thread_f, NULL);

    uv_run(loop, UV_RUN_DEFAULT);

    return 0;
}
@bnoordhuis
Copy link
Member

You're accessing the uv_loop_t from two threads. That's not safe.

Put another way: you're allowed to call uv_async_send() from another thread but not uv_async_init() or uv_close().

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants