VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 127
声望: 13

目前遇到的情况是:
多账号下,偶发的gateway.close()主动退出会导致卡死(退出是发出事件,注册的函数执行gateway.close(),通过打印发现,基本上是tdapi下的self.exit()后面的打印没能打印,怀疑是self.exit偶发故障)

怀疑是

int TdApi::exit()
{
    this->active = false;
    this->task_queue.terminate();
    this->task_thread.join();

    this->api->RegisterSpi(NULL);
    this->api->Release();
    this->api = NULL;
    return 1;
};

上述代码中的task_thread.join();会引起(动态链接库层面的异常导致)阻塞后无法退出的情况吗?

Member
avatar
加入于:
帖子: 127
声望: 13

搜索CTP相关资料时,找到这么一篇文章,https://blog.csdn.net/zhangzq86/article/details/49583993?utm_source=copy

其中提到:

三、CTP退出
调用Release函数即可,不需要delete的
这里要注意的是:在Release之前不需要调用RegisterSpi(NULL);注销Spi的,如果这样做了,有可能导致CTP退不出的。

而vnpy的ctp封装,正是先调用了RegisterSpi然后再Release释放的。

Member
avatar
加入于:
帖子: 127
声望: 13

经过验证,貌似不是的锅。还是主贴中的join引起。

我将tdapi中的exit逐行打印注释,


int TdApi::exit()
{
    this->active = false;
    this->task_queue.terminate();
    std::cout<<"terminate ok\n";
    this->task_thread.join();
    std::cout<<"join ok\n";
    this->api->RegisterSpi(NULL);
    std::cout<<"RegisterSpi ok\n";
    this->api->Release();
    std::cout<<"Release ok\n";
    this->api = NULL;
    std::cout<<"NULL ok\n";
    return 1;
};

在多次长时间实测后会偶然复现无法退出的现象,日志打印如下:

2022-05-25 10:21:49.872169 id1_xxx执行登出操作开始。(gateway)
id1_xxx执行登出。(gateway)
terminate ok (pyd)
join ok (pyd)
RegisterSpi ok (pyd)
Release ok (pyd)
NULL ok (pyd)
id1_xxx 执行登出操作完毕。 (gateway)
2022-05-25 10:21:49.894205 id2_xxx 执行登出操作开始。 (gateway)
id2_xxx执行登出。(gateway)
terminate ok (pyd)

也就是说,id2退出时,this->task_thread.join();这句话未能执行完,卡在这了。

而由于退出操作是以事件形式执行,进而导致事件引擎卡在这个事件处理上,最终整个ui卡住。

Member
avatar
加入于:
帖子: 387
声望: 20

this->task_thread.join();

是等待C++向Python推送数据的线程运行结束,所以有可能因为Python那边的对象已经被销毁(或者阻塞)导致卡住了,如果确定只是在关闭系统的时候退出的话,感觉可以直接不管这个join吧,反正进程都退出了。

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】