线程

来源:互联网 发布:中国女性受侵害数据 编辑:程序博客网 时间:2024/05/24 05:51

我们都知道进程有各自的PCB。并且在各自独立的地址空间上运行。那么什么是线程呢?

一、线程概念
有时候一个进程中同时需要执行多个控制流程。比如,你开着迅雷下载电影,还能一边下载一边观看。并且能够拖动边框。这时候就是线程排上用场的地方了。
1.很多时间我们会听到,线程是在进程里运行的。这句话其实是说线程是在进程的地址空间内部运行的。所有线程是进程内部的一个执行流,线程只拥有进程的一部分资源。理所当然线程的粒度小于进程。
2.调度的基本单位其实是线程,而进程则是负责调用和分配资源的前提和基本单位。
3.在linux下线程是轻量级进程。
4.LInux下其实并没有真正意义上的线程。线程是由第三方库根据进程模拟出来的。
二、线程共享资源
1.文件描述符。线程共享文件描述符,因此一个线程打开某个文件,所有线程都可见。
2.每种信号,以及各种自定义的信号。
3.当前工作目录。
4.用户id 和组id。
三、线程私有的资源
1.线程id。每个线程都有一个id方便操作系统管理。
2.上下文,其中包括各种寄存器的值,程序计数器和栈指针。
这里要说明一下,加入进程因为某种原因暂停工作挂起。里面的所有运行的线程都会保护当前状态存储当前状态,以便下次唤醒后继续运行。所以上下文是必要的私有。
3.运行时栈空间。每个线程运行起来都是会创建一个运行时栈,保证独立运行。来存放局部变量这些。
4.errno变量。
5.信号屏蔽字。
6.调度优先级。因为调度的基本单位是线程。
四、创建线程
线程创建通过调用pthread_create函数来创建其他线程。

#include<pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(start_routine)(void*),void *ary);

参数1 :输出新创建线程id。参数2:线程属性通常设置NULL。参数3:函数指针指向所有要创建的线程,即创建的线程将要跑的函数。参数4:输出型参数,传递给该函数的指针。
返回值:成功返回0;失败返回错误码。
这里写图片描述
注意:编译的时候要gcc -o mythread mythread.c -lpthread
后面加上-lpthread 。才可以编译通过
结果这里写图片描述
结果可以看到主线程和创建的新线程的pid是一样的证明他们在同一个进程的地址空间内运行,但是tid不同,证明是私有的tid。
五、线程终止
一个线程终止的方法有很多,return啊,exit啊都可以。因为这些都是让进程终止。当然线程也会挂掉。
但是只让线程终止,而进程不受影响方法有以下:
1:从线程函数里return,当然这个return不包括在主线程return。那样进程也会终止。
2:可以使用一个线程调用pthread_cancel终止同一个进程里的其他进程。
3:调用pthread_exit终结自己。

#include<pthread.h>void pthread_exit(void *retval);

retval 是一个指针,调用pthread_join可以获得。
六、线程等待
线程如进程一样在新线程退出时,需要回收资源以及退出码。如果此时主线程先退出,则会产生类似于僵尸进程一样的线程,占资源,因此在主线程引入线程等待,来防止主线程提前退出。

#include<pthread.h>int pthread_join(pthread_t thread,void **retval);

参数1:要等待的线程id。参数2:等待目标线程的退出码。
当热,线程等待是阻塞式等待。
以下来掩饰进程等待:

#include<stdio.h>#include<pthread.h>#include<stdlib.h>void * thread_run1(void * arg){    printf("thread1 is running....\n");printf("perr thread1 pid= %d,tid=%u\n",(int)getpid(),(unsigned long long )pthread_self());    return(( void*)1);}int main(){    pthread_t tid;    void *retcode;    int err=pthread_create(&tid,NULL,thread_run1,NULL);    if(err!=0)    {        printf("create thread err:%s\n",strerror(err));        exit(err);    }    int ret=pthread_join(tid,&retcode);    printf("join_ret:%d",ret);    printf("thread return ,thread id is: %u,return code is :%d\n",(unsigned long)tid,(int*)retcode);    sleep(1);    return 0;}

结果:这里写图片描述

原创粉丝点击