Linux 内核线程创建
来源:互联网 发布:比特币挖矿程序 mac 编辑:程序博客网 时间:2024/05/16 15:02
在Linux内核中,创建线程函数为__kthread_create_on_node(),需要注意的是
内核创建一个内核线程是个异步过程。
函数__kthread_create_on_node对外提供两个函数
一,__kthread_create_worker
二,kthread_create_on_node
当然我们主要使用二这种形式。对于二这种形式,内核简单定义了宏:
#define kthread_create(threadfn, data, namefmt, arg...) \ kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg)
这样方便通过kthread_create来创建内核线程。
需要注意,__kthread_create_on_node()函数并不执行真正的内核线程创建,而是创建一个对象,然后把对象递交一个
链表上面,唤醒创建内核线程的线程来执行创建。而原先的创建者则进行等待。
这里封装的数据结构为struct kthread_create_info。
存放在kthread_create_list链表上面。
创建线程的线程是kthreadd,其在内核启动的早期初始化。
static noinline void __ref rest_init(void){ int pid; kernel_thread(kernel_init, NULL, CLONE_FS); numa_default_policy(); pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); rcu_read_lock(); kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);}
int kthreadd(void *unused){ struct task_struct *tsk = current;
/* Setup a clean context for our children to inherit. */ set_task_comm(tsk, "kthreadd"); ignore_signals(tsk); set_cpus_allowed_ptr(tsk, cpu_all_mask); set_mems_allowed(node_states[N_MEMORY]);
current->flags |= PF_NOFREEZE;
for (;;) { set_current_state(TASK_INTERRUPTIBLE); if (list_empty(&kthread_create_list))如果为真,继续放弃CPU。 schedule(); __set_current_state(TASK_RUNNING);设置内核线程状态
spin_lock(&kthread_create_lock); while (!list_empty(&kthread_create_list)) {取得链表每个元素进行创建内核线程 struct kthread_create_info *create;
create = list_entry(kthread_create_list.next, struct kthread_create_info, list); list_del_init(&create->list); spin_unlock(&kthread_create_lock);
create_kthread(create);//真正创建处理
spin_lock(&kthread_create_lock); } spin_unlock(&kthread_create_lock); }
return 0;}
static void create_kthread(struct kthread_create_info *create){ int pid;
#ifdef CONFIG_NUMA current->pref_node_fork = create->node;#endif /* We want our own signal handler (we take no signals by default). */ pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
需要注意这里给的是kthread,所以,所有的内核线程第一个函数都是kthread if (pid < 0) { /* If user was SIGKILLed, I release the structure. */ struct completion *done = xchg(&create->done, NULL);
if (!done) { kfree(create); return; } create->result = ERR_PTR(pid); complete(done);唤醒原先需要创建线程的线程 }}
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags){ return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, (unsigned long)arg, NULL, NULL, 0);fork处理}
- linux 内核线程创建
- linux内核线程 [创建]
- linux内核创建线程
- Linux 内核线程创建
- linux 创建内核线程
- linux内核线程的创建
- Linux内核中创建线程
- Linux 内核线程 的 创建 和 终止
- linux内核线程创建销毁机制
- linux内核线程创建销毁机制
- linux内核线程的创建与销毁
- linux内核线程的创建与销毁
- linux内核线程的创建与销毁
- linux下创建用户线程和内核线程
- Linux内核-内核线程
- 创建内核线程
- kthread_run 创建内核线程
- 内核线程创建
- ShareSdk
- listview侧滑菜单
- hdu 1533 KM匹配
- 【CQOI2014】排序机械臂
- leetcode [Count and Say]
- Linux 内核线程创建
- js实现日历效果
- fatal error C1900: “P1”(第“20080116”版)和“P2”(第“20070207”版)之间 Il 不匹配
- linux压缩与解压命令
- 基于CentOs7的moodle平台搭建历程
- 我的新博客
- JAVA从入门到精通(16)-- Java版JSON入门
- 排序
- Oracle DB内存分配: 使用HugePage、tmpfs