Linux 内核线程创建

在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处理
}
 
 
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值