下面讲解dataman的原理.
图1 dataman文件目录结构
图 2 dataman的命令接口
图3: dataman提供外部接口有下面
图 4 dataman提供的dm_read接口的外部调用者
问题? 外部多个线程去访问dataman的dm_read函数,那么如何实现多线程访问的冲突??
图5 dm_read的调用关系
为了我们方便快速的调用关系,我们采用打log的方式进行跟踪, 下面我答log的位置都贴了出来, 我们自己添加1个test命令!
图6 添加的log信息
链接: https://github.com/yangang123/cpp_test/blob/develop/doc/dataman.c
先在nsh中关闭dataman,然后重新打开dataman ,
nsh> dataman stop
nsh> dataman start
dataman: Power on restart, data manager file '/fs/microsd/temdata' size is 128050 bytes
nsh> dataman: b
nsh>
看到【dataman】线程阻塞到了b的位置, 线程正在等待px4_sem_wait(&g_work_queued_sema);
/* Tell startup that the worker thread has completed its initialization */
px4_sem_post(&g_init_sema);
/* Start the endless loop, waiting for then processing work requests */
while (true) {
/* do we need to exit ??? */
if ((g_task_should_exit) && (g_fd >= 0)) {
/* Close the file handle to stop further queuing */
g_fd = -1;
}
warnx("b");
if (!g_task_should_exit) {
/* wait for work */
px4_sem_wait(&g_work_queued_sema);
}
warnx("c");
/* Empty the work queue */
while ((work = dequeue_work_item())) {
warnx("d");
通过dataman test命令,进行调用一次dm_read, 分析过程, 通过下面的调试信息,我们已经分析到了程序已经跳过了阻塞的b的位置,这个是由于dm_read会给线程发送g_work_queued_sema信号量。