一,前言
前言本节主要看线程什么时候创建的及创建的线程有什么作用。
二,源码分析
第一次进入断点仅主线程4215.
root@ubuntu:/home/applecai# ps -T -p 4215
PID SPID TTY TIME CMD
4215 4215 pts/8 00:00:00 qemu-system-gnu
- 通过搜索文件名pthread关键字,然后找到qemu-thread-posix.c直接在err = pthread_create(&thread->thread, &attr, start_routine, arg);打断点第一次进入断点的调用关系,不是main开始的,因为rcu_init函数被__attribute__((__constructor__))修饰,所以在main前就进行了执行。
- 第二次进入断点。主要是cm_object_realize一直调用,最后调用qemu_init_vcpu的时候创建了一个线程。
总的来说cpu是单核的,所以仅一个线程,那么总共就是3个线程了。
root@ubuntu:/home/applecai# ps -T -p 4215
PID SPID TTY TIME CMD
4215 4215 pts/8 00:00:00 qemu-system-gnu
4215 4344 pts/8 00:00:00 qemu-system-gnu
4215 4514 pts/8 00:00:08 qemu-system-gnu
- 虚拟cpu创建线程来运行传入的elf这个功能比较好理解,但是一开始rcu_init创建的线程干嘛用的?
看了下rcu.h文件,外部确实有调用call_rcu的,然后看着这个rcu关键字好熟悉啊,网上搜索了下linux也用这种锁,就是read-copy-update,主要用于写的线程少,执行次数少,而读取的线程多,执行次数多的情况。这样读取的时候需要加锁,仅写的时候加锁,可以提高并行效率,写的时候加锁更新为一个新的链表,而读取正在执行就的链表不删除,而将要读取的就用新链表了,等旧的链表引用着都消失了,就把这个old链表删除。这样看对象好像仅是链表节点。其中synchronize_rcu函数就是用来释放资源的,看了下rcu.c代码感觉比较复杂,但是主要逻辑就是这样的。
三,小结
rcu.txt中也有相关rcu的使用描述。只是我在想,干嘛不用linux中自带的rcu api,qemu要自己写一个呢?然后我网上搜索了下linux自带的rcu,那么更加复杂了,还要关注休眠唤醒热插拔什么的,怪不得qemu这个应该是简单版本。看来qemu的rcu.c和h中的源码我要做个小专题专门学习下,这样是否我也可以开发一个简单版本的rcu了,哈哈~
标签:4215,00,Apple,rcu,链表,源码,线程,qemu,Qemu From: https://blog.51cto.com/u_16247275/7502695