线程

来源:互联网 发布:淘客cms系统哪个好 编辑:程序博客网 时间:2024/05/29 13:17

1、线程的概念
线程是系统执行的最小单位;进程是资源分配的最小单位。
线程是进程中的一条执行流,进程至少有1个线程,进程也可以有多个线程,也就是多个执行流在同时执行。由于同一进程的多个线程共享同一地址空间,因此线程之间有互相共享的资源,也有彼此独占的资源。
2、线程之间共享的资源
地址空间、数据段和代码段、全局变量、文件描述符表、信号处理方式、用户ID和组ID、当前工作目录。
3、每个线程各有一份的资源
线程ID、上下文(寄存器,程序计数器,栈指针)、栈空间、状态字、信号屏蔽字、调度优先级。
4、线程的类型

  • 用户态:如图所示,第一列用户态进程中有3个线程,但在内核态中只有一条线程,其3个线程在用户态中记录

  • 内核态:如图所示,第二列在用户态中只有一个进程一个线程,但在进入内核态中显示3个线程,并在内核态中记录。

  • 混合模式:如图所示,第三列用户态的进程中有4个线程,在内核态中有3个线程,则合二为一的2个线程记录在用户态中,内核态中的3个线程记录在内核态中,即N对M的关系,并且内核态中的线程一定小于用户态中的线程数。

这里写图片描述
5、创建线程
例如:有两个需要:
第一条:循环输出“hello”,输出5次,每隔2s输出一次;
第二条:循环输出“pthread”,输出3次,每隔3s输出一次;
由于考虑到资源分配的问题,这时候就会采用创建线程来节省空间并简化问题。
创建线程函数:
int pthread_create(pthread_t pthread,const pthread_attr_t *attr,void(pthread_fun)(void),void*arg)
其中第一个参数为获取的线程号;第二个参数为线程属性(一般为NULL,表默认),第三个参数是线程函数(函数指针,函数本身即为地址),第四个参数为传递的参数。
eg:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<assert.h>#include<pthread.h>void* pthread_fun(void *arg){int i=0;for(;i<3;++i){printf("pthread\n");sleep(3);}}void main(){pthread_t tid;pthread_create(&tid,NULL,pthread_fun,NULL);assert(res==0);int i=0;for(;i<5;++i){printf("hello\n");sleep(2)}}编译:gcc -o main main.c -lpthread(必须加上线程库)执行结果:hello         pthread        hello        pthread        hello        pthread        hello        hello

6、终止线程
主线程结束,默认调用exit函数,结束进程;函数线程结束,默认调用pthread_exit函数,结束线程本身。
终止线程函数:
void pthread_exit(void *reval);//参数为线程结束数据(线程退出码)
仅仅结束线程本身,进程不会结束。

//例如将主线程中的睡眠改为1秒,则函数线程需要9s,而主线程只需要5s,则需要采用终止线程函数,以此来只结束线程,不结束进程。#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<assert.h>#include<pthread.h>void* pthread_fun(void *arg){int i=0;for(;i<3;++i){printf("pthread\n");sleep(3);}}void main(){pthread_t tid;pthread_create(&tid,NULL,pthread_fun,NULL);int i=0;for(;i<5;++i){printf("hello\n");sleep(1)}pthread_exit(NULL);//仅仅结束线程本身,进程不会结束}不加终止进程函数时执行结果为:        hello                pthread        hello        hello        pthread        hello        hello加了终止进程函数时执行结果为:        hello                pthread        hello        hello        pthread        hello        hello        pthread

7、等待线程

  • 阻塞运行,直到指定的线程结束

  • join函数可以获取线程退出时候pthread_exit函数填充的数据

等待线程函数:
int pthread_join(pthread_t pthread,void **reval)
第一个参数为等待的线程,第二个参数为获取线程结束时填充的数据。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<assert.h>#include<pthread.h>void* pthread_fun(void *arg){int i=0;for(;i<3;++i){printf("pthread\n");sleep(5);}pthread_exit("pthread over");}void main(){pthread_t tid;pthread_create(&tid,NULL,pthread_fun,NULL);char *rval;pthread_join(tid,&rval);printf("%s\n",rval);int i=0;for(;i<5;++i){printf("hello\n");sleep(2)}pthread_exit(NULL);//仅仅结束线程本身,进程不会结束}执行结果:pthread         pthread        pthread        pthread over        hello                hello        hello        hello
原创粉丝点击