我正在使用嵌入式Linux内核开展项目,并且在访问闪存时遇到线程延迟问题。
我的应用程序是多线程的,有些线程必须在不到500毫秒的时间内完成给定的任务。问题是这些线程有时会在超过1秒的时间内被“冻结”,而我的500毫秒执行时间会被延长。
这种行为似乎与闪存写入有关,因为当我从shell执行“dd”命令以在闪存中连续写入时也会发生这种情况。
我尝试了各种配置:
通过使用ftrace工具,我可以看到,在“冻结”时间内,一些线程和进程仍在运行,其他任务之间有很多“空闲”任务时间(空闲任务时隙持续时间> 20ms ):
我不明白:
我怀疑与内核中的IO管理有关的东西,好像内核抢占了每个非IO线程,以便完成与IO相关的所有工作(网络,文件......)。
有没有人知道可能导致这种延迟的原因?
我的内核设置:
编辑:
由于我不是专家,我与你分享ftrace capture(用kernelshark查看): https://drive.google.com/file/d/0B6pJb20-D0D2NHZBUHJVRlV0aDg/view?usp=sharing
也许它可以帮助您了解我的系统上发生了什么。
在这次捕获中,我使用外部“dd”命令重现了我在名义条件下遇到的类似行为。
在时间戳上,“洞”(“冻结”)是(我的应用程序中不再有自定义的ftrace标记):
另一个小“洞”
答案 0 :(得分:2)
我认为这可能是因为内核已经决定它必须刷新一些文件系统元数据,或者做其他文件系统内务处理,并且必须停止你的进程,直到它做得足够。
我遇到了类似的问题,并使用多线程和用户空间缓冲来吸收停顿。请参阅my old question and answer here。
答案 1 :(得分:-1)
我更新了这个主题的状态:我们认为我们找到了锁定的根本原因。
我公司聘请了一位Linux专家2天。
感谢他,我们发现:
锁是由内核完成数据刷新时所有闪存访问被阻止引起的。
特别是我们的记录器模块(用于时间戳...),它调用syslog()函数。
但是这个syslog()函数也会阻塞进程,即使syslogd守护进程是访问flash的真正进程... (我们怀疑用于syslog通信的unix套接字阻塞,直到资源可用,比如bash管道' |'当将大量日志写入闪存中的文件时)。
解决方案是通过对隔离线程进行日志/闪存访问(使用非阻塞自定义消息队列作为通信项目),在实时线程和另一个线程之间拆分对闪存的所有访问权限。
似乎它有效!
我之前没有读过蓝调回答,但似乎他是对的; - )