c++ - localtime() 函数正在调用 ___lll_lock_wait_private() 这使线程陷入死锁
问题描述
我看到很多问题___lll_lock_wait_private ()
都陷入僵局。但他们的调用堆栈是不同的。他们的代码是调用malloc()
or free()
or fork()
。
但就我而言,我有一个 Log 类,它正在尝试打印日志。该日志使我的线程陷入僵局。
请参阅下面的调用堆栈,
#0 0x000000fff4c47b9c in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x000000fff4bf0364 in __tz_convert () from /lib64/libc.so.6
#2 0x000000fff4bee2c0 in localtime () from /lib64/libc.so.6
#3 0x000000fff5167188 in getTimeStr() () from /usr/sbin/sajet/sharedobj/liblibLite.so
#4 0x000000fff516756c in LogClass::logBegin() () from /usr/sbin/sajet/sharedobj/liblibLite.so
#5 0x000000fff5318c90 in DaemonCtrlServer::strtDaemon(daemonInfo&) () from /usr/sbin/sajet/sharedobj/libDaemonCtlServer.so
#6 0x000000fff531abc0 in DaemonCtrlServer::restrtDiedDaemon(daemonInfo&) () from /usr/sbin/sajet/sharedobj/libDaemonCtlServer.so
#7 0x000000fff531ae64 in DaemonCtrlServer::handleChildDeath() () from /usr/sbin/sajet/sharedobj/libDaemonCtlServer.so
#8 0x00000000100080ac in sj_initd::DaemonDeathHandler() ()
#9 0x000000001000b8f8 in sj_initd::SignalHandler(int) ()
#10 0x00000000100080e8 in sj_initd_SigHandler::sj_initdSigHandler(int) ()
#11 <signal handler called>
#12 0x000000fff4bedc00 in __offtime () from /lib64/libc.so.6
#13 0x000000fff4bf02a8 in __tz_convert () from /lib64/libc.so.6
#14 0x000000fff4bee2c0 in localtime () from /lib64/libc.so.6
#15 0x000000fff5167188 in getTimeStr() () from /usr/sbin/sajet/sharedobj/liblibLite.so
#16 0x000000fff516756c in LogClass::logBegin() () from /usr/sbin/sajet/sharedobj/liblibLite.so
#17 0x000000fff52e868c in ConnectionOS::ProcessReadEvent() () from /usr/sbin/sajet/sharedobj/libconnV2.so
#18 0x000000fff52ef354 in ConnectionOSManager::ProcessConns(fd_set*, fd_set*) () from /usr/sbin/sajet/sharedobj/libconnV2.so
#19 0x000000fff52f0a0c in SocketsManager::ProcessFds(bool) () from /usr/sbin/sajet/sharedobj/libconnV2.so
#20 0x000000fff52c51b4 in EventReactorBase::IO (this=0x19a65e80) at EventReactorBase.cpp:361
#21 0x000000fff52c457c in EventReactorBase::React (this=0x19a65e80) at EventReactorBase.cpp:419
#22 0x000000fff52c10cc in Task::Run (this=0x19a65e30) at Task.cpp:222
#23 0x000000fff52c1218 in startTask (t=0x19a65e30) at Task.cpp:152
#24 0x000000001000a9c4 in TaskManager::Start() ()
#25 0x0000000010007538 in main ()
sj_init 是一个守护进程,它监视系统中其他守护进程的实时状态。当一个守护进程死掉(关闭与 sj_init 的连接)时,它会尝试重新启动该守护进程。然后,startDaemon()
正在尝试打印一个日志,该日志正在调用getTimeStr()
which 内部调用___lll_lock_wait_private
编辑
由于localtime
不是线程安全的,我尝试过,localtime_r
但它也导致线程陷入死锁。但符合。localtime_r
描述这是线程安全的功能。我在这里做错了什么?
解决方案
信号处理程序中的程序阻塞在__tz_convert()
从localtime()
. 信号处理程序中断__tz_convert()
从 调用localtime()
。
#0 0x000000fff4c47b9c in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x000000fff4bf0364 in __tz_convert () from /lib64/libc.so.6
#2 0x000000fff4bee2c0 in localtime () from /lib64/libc.so.6
...
#11 <signal handler called>
...
#13 0x000000fff4bf02a8 in __tz_convert () from /lib64/libc.so.6
#14 0x000000fff4bee2c0 in localtime () from /lib64/libc.so.6
...
#25 0x0000000010007538 in main ()
localtime()
似乎不能重入。
信号处理程序只能调用一组非常特定的函数。在此处向下滚动:https ://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03
localtime()
不在这个集合内。
信号处理程序应该简短而简单。
您可以设置一个线程来执行格式化和记录,例如通过管道由信号处理程序提供所有必要的信息来格式化和记录。这样做的功能列在上面链接的集合中。
推荐阅读
- mongodb - 如果存在则更新,如果不在 mongodb 中则插入
- linux - Ubuntu 下的 Qt - 输入重音符号
- laravel - 如何在流明中从 mongo db 中检索数据
- flutter - 在颤动中使用相机包没有点击和预览图片
- azure-pipelines - 无法在 Azure 上为 ARM64 上的模块构建映像以用于 iotedge 管道
- r - 由 / 分隔的嵌套列表的列
- php - Wordpress wp_send_json_success() 成功返回 undefined
- sql - 连接两个表以保留选定的值和空值
- python - 终端找不到 PyCharm 中导入的模块
- python - 获取主键 django 的问题