我正在使用嵌入式Linux内核进行一个项目,在访问闪存时遇到线程延迟问题。
我的应用程序是多线程的,有些线程必须在不到500 ms的时间内完成给定的任务。问题是,这些线程有时会在超过1秒的时间内被“冻结”,而我的500 ms的执行时间被超过了。
这种行为似乎与flash写相关联,因为当我从shell执行"dd“命令以在闪存中连续写入时,它也会发生。
我尝试了各种配置:
通过使用ftrace工具,我可以看到,在“冻结”时间期间,一些线程和进程仍在运行,其他任务之间存在大量“空闲”任务时间(空闲任务时隙持续时间>20 is ):
我不明白:
我怀疑与内核中的IO管理有关的东西,好像内核抢占了每个非IO线程,以便完成与IO (网络、文件、.)有关的所有工作。
有没有人知道什么会导致这种延迟?
我的内核设置:
编辑:
因为我不是专家,所以我和你分享ftrace (用核鲨鱼观看):https://drive.google.com/file/d/0B6pJb20-D0D2NHZBUHJVRlV0aDg/view?usp=sharing
也许它能帮你看看我的系统里到底发生了什么。
在这个捕获中,我使用外部"dd“命令复制了我的应用程序在名义状态下遇到的类似行为。
“孔”(“冻结”)在时间戳处(不再是来自我的应用程序的自定义ftrace标记):
又一个小“洞”
发布于 2015-04-13 12:56:27
我认为这可能是因为内核已经决定它必须刷新一些文件系统元数据,或者进行其他文件系统内部管理,并且必须延迟您的进程,直到它完成了足够的工作。
我有类似的问题,并使用多线程和一个用户土地缓冲区来吸收货摊。见my old question and answer here。
发布于 2015-07-01 17:25:02
我更新这个主题的状态:我们认为我们找到了锁的根本原因。
我的公司雇佣了一位Linux专家,为期2天。
多亏了他,我们发现:
这些锁是由内核完成数据刷新时阻止所有闪存访问造成的。
特别是我们的记录器模块(用于时间戳)调用syslog()函数。
但是这个syslog()函数也阻塞了进程,即使syslog守护进程是访问flash的真正进程.(我们怀疑用于syslog通信块的unix套接字,直到资源可用为止,就像在将大量日志写入闪存文件时使用的bash管道“AC.26”)。
解决方案是在实时线程和其他线程之间拆分对闪存的所有访问,方法是将日志/闪存访问拆分为一个独立的线程(使用一个非阻塞的自定义消息队列作为通信项)。
而且看起来很管用!
我以前没有读过蓝色的答案,但他似乎是对的。
https://stackoverflow.com/questions/29127047
复制相似问题