1.用户级线程和内核级线程
哪些是用户级线程?
用户级线程内核的切换由用户态程序自己控制内核切换,不须要内核干涉,少了进出内核态的消耗,但不能挺好的借助多核Cpu,目前Linuxpthread大体是如此做的。
哪些是内核级线程?
切换由内核控制,当线程进行切换的时侯,由用户态转化为内核态。切换完毕要从内核态返回用户态,被称为内核支持的线程或轻量级进程。
关于用户级线程和内核级线程可参考:
2.进程ID,内核线程ID,用户态线程ID
进程ID
这儿所说的进程ID指我们通过fork创建子进程linux操作系统安装,子进程和父进程在内核中独立运行,但是一个进程对应一个进程描述符(PCB),PCB中包含了进程的ID,通过getpid返回当前进程ID
内核线程ID
linux下,内核中,并不存在线程这一说,而是通过复制了进程的PCB作为标示自己(线程),作为进程的一个执行分支;既然有进程描述符(PCB)标示,自然就有一个标示符(ID)来标示着我是你(进程)的哪一个分支,这个标示符(ID)就是内核中的线程ID,通过syscall获得
用户态线程ID
里面提及用户级线程,对线程的操控是由用户自己来完成,这么对此线程操控,用户晓得你是哪一个线程,甚或又有了用户态的线程ID;这儿我们通过pthread_self()函数获得注:这儿的ID是一个地址,而不是向下面两个ID是一个整数linux pthread,下边验证
3.线程组
哪些是线程组?
多线程的进程又被称为线程组,线程组内的每一个线程在内核之中都存在一个进程描述符(task_struct)与之对应。个人理解:虽然就是拥有多个线程的进程的描述符,一个结构体,上面储存着自己的一些信息,而且还有标示自己是这种多线程的领头的信息structtask_struct{...pid_tpid;//内核级线程id,(个人猜想:内核听到他是一个进程,所以为pid)pid_ttgid;//用户级进程id,(个人猜想:用户听到他是一个线程,所以为tgid)...structtask_struct*group_leader;//线程组表针,表针指向自己,表示是主线程...structlist_headthread_group;//标示我是一个线程组...};
线程组ID?
线程组的ID和主线程ID保持一致
线程组的特征?
线程组内的第一个线程linux伊甸园,在用户态被称为主线程(mainthread),在内核中被称为groupleader。内核在创建第一个线程时,会将线程组的ID的值设置为第一个线程的线程ID,group_leader表针则指向自身linux pthread,即主线程的进程描述符。即线程组显存在一个线程,线程ID等于进程ID,该线程被称为主线程。在进程中有父进程的概念,并且在线程中所有的线程都是对等关系。
出来我们通过实例来看一下线程ID和进程ID以及线程组
4.获取线程ID函数
内核级线程ID——syscall()
#includepid_ttid;tid=syscall(SYS_gettid);
用户态线程ID——-pthread_self()
#include
pthread_tpthread_self(void);返回值:成功返回0,失败返回错误码
实例:
#include#include#include
#include#include#includevoid*thread_run(void*arg){(void)arg;pid_tpid=syscall(SYS_gettid);while(1){printf("Iamthread->进程ID:%d->内核线程ID:%d->用户态线程ID:%lxn",getpid(),pid,pthread_self());sleep(1);}}intmain(){pid_tpid=syscall(SYS_gettid);//获取内核中的线程IDintret;pthread_ttid;ret=pthread_create(&tid,NULL,thread_run,NULL);if(ret!=0){perror("pthread_create");exit(1);}while(1){printf("Iammain->进程ID:%d->内核线程ID:%d->用户态线程ID:%lxn",getpid(),pid,pthread_self());sleep(1);}return0;}
结果:
进程ID、用户级线程ID、内核级线程ID
线程组ID
更多linux免费视频资料获取后台私信【架构】