线程与进程在内核中的实现

来源:互联网 发布:淘宝剑三升级代练 编辑:程序博客网 时间:2024/05/01 11:01
内核代码为2.6.35.13。

1      概述

进程与其对应的线程之间使用相同的内存空间、文件描述符和一些其他的东西。

2      分析

在内核中,线程与进程都是用结构体task_struct来表示的,在内核调度上并没有什么区别。

2.1         相同点

我们已经在上文中指出主线程与线程之间使用相同的内存空间、文件描述符和一些其他的东西。

#include <stdio.h>

#include <pthread.h>

 

void *thread1(void *data)

{

    while (1){

        printf("thread 1\n");

        sleep(1);

    }

    pthread_exit(0);

    return;

}

 

void *thread2(void *data)

{

    while (1){

        printf("thread 2\n");

        sleep(2);

    }

    pthread_exit(0);

    return;

}

 

int main()

{

    pthread_t th1;

    pthread_t th2;

 

    if (pthread_create(&th1, NULL,thread1, NULL)){

        return 1;

    }

    if (pthread_create(&th2, NULL,thread2, NULL)){

 

        return 1;

    }

 

    pthread_join(th1, NULL);

    pthread_join(th2, NULL);

 

    return 0;

}

为了验证这些观点,我以上面的用户态代码示例来说明(代码不一定规范,仅为说明问题)。如上代码,在主线程成创建了两个线程thread1和thread2,然后就等待这两个线程执行完成,但这两个线程都一直在死循环中,也就说,整个都不为结束,除非我手动杀掉这个进程。

在内核中编写(test)模块来查看这三个(主)线程之间的关系,代码如下:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/sched.h>

#include <asm/string.h>

 

static void print_task(struct task_struct *p)

{

    printk(KERN_ALERT "pid: %d,tgid: %d, mm = %p, files = %p\n",

           p->pid, p->tgid, p->mm, p->files);

    return;

}

 

static int hello_init(void)

{

    struct task_struct *g =NULL;

    struct task_struct *t =NULL;

    printk(KERN_ALERT "\ntestmodule init\n");

 

    do_each_thread(g, t){

       if (!strcmp(g->comm,"a.out")) {

           print_task(t);

       }

    }while_each_thread(g,t);

 

    return 0;

}

static void hello_exit(void)

{

    printk(KERN_ALERT "test moduleexit\n");

}

 

MODULE_LICENSE("DualBSD/GPL");

module_init(hello_init);

module_exit(hello_exit);

如上代码,轮训当前所有的线程,找到名称为“a.out”的线程(即以上用户态代码生成的线程)。打印对应线程的pid、tgid、mm和files。其中,pid表示线程的一个标识;tgid即threadgroup id,表示该线程组的id,其实也就是主线程的id;mm表示该task使用的内存空间;file表示该task所有打开的文件描述符。运行结果如下:

 

从上述结果中可以看出,主线程和两个辅线程都拥有各自的pid,但其tgid都等于主线程的pid,而且他们的mm和files也指向同样的一块内存,也就是说:主线程和辅线程之间的确共享着内存空间和文件描述符信息

在内核中,调度主线程和辅线程是没有区别的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

0 0
原创粉丝点击