Linux下线程的创建

mac2024-10-18  68

POSIX线程库:

与线程有关的函数构成一个完整的系列,大多数函数的名字以“pthread_”开头,而要使用这些函数需要引入头文件<pthread.h>,在编译时需追加-lpthread链接函数库

#线程创建:

//功能:创建一个线程 //函数原型: int pthread_creat(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void*), void *arg); thread:返回线程id attr:设置线程属性,一般置NULL start_routine:函数地址,线程启动后要执行的函数 arg:传给线程启动函数的参数 返回值:成功返回0,失败返回错误代码

##线程id:

       在Linux中,目前的线程实现是Native POSIX Thread Libaray,简称NPTL。在这种实现下,线程又被称为轻量级进程(Light Weighted Process),每一个用户态的线程,在内核中都对应一个调度实体,也拥有自己的进程描述符(task_struct结构体)。

struct task_struct{ pid_t pid; pid_t tgid; ... struct task_struct *group_leader; struct list_head thread_group; };

         多线程的进程,又被称为线程组,线程组内的每一个线程在内核之中都存在一个进程描述符(task_struct) 与之对应。进程描述符结构体中的pid,表面上看对应的是进程ID,其实不然,它对应的是线程ID;进程描述符中的tgid,含义是Thread Group ID,该值对应的是用户层面的进程ID.

 

ps命令中的-L选项,会显示如下信息:

LWP:线程ID,既gettid()系统调用的返回值NLWP:线程组内线程的个数

        线程组内的第一个线程,在用户态被称为主线程(main thread),在内核中被称为group leader,内核在创建第一个线程时,会将 线程组的ID的值设置成第一个线程的线程ID,group_leader指针则指向自身,既主线程的进程描述符。所以 线程组内存在一个线程ID等于进程ID,而该线程即为线程组的主线程。

/* 线程组ID等于线程ID,group_leader指向自身 */ p->tgid = p->pid; p->group_leader = p; INIT_LIST_HEAD(&p->thread_group);

##线程地址空间

pthread_ create函数会产生一个线程ID,存放在第一个参数指向的地址中。该线程ID和前面说的线程ID不是 一回事。前面讲的线程ID属于进程调度的范畴。因为线程是轻量级进程,是操作系统调度器的最小单位,所以需要 一个数值来唯一表示该线程。pthread_ create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。线程库NPTL提供了pthread_ self函数,可以获得线程自身的ID:对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID,本质就 是一个进程地址空间上的一个地址。
最新回复(0)