关于多线程,需要看https://blog.csdn.net/column/details/killthreadseries.html
大神写的专题
1.线程概念
线程是CPU使用的基本单元,它由线程ID、程序计数器、寄存器集合和栈组成。它与属于同一进程的其他线程共享代码段、数据段和其他操作系统资源,如打开文件和信号。
2.模型
多对一 一对一 多对多
3.线程支持:
用户层的用户线程:受内核支持,无需内核管理
内核层的内核线程:操作系统直接支持和管理
4.线程库
为程序员提供创建和管理线程的API
(1)在用户空间提供没有内核支持的库,所有代码和数据结构都存放于用户空间;调用库的一个函数只是导致了用户空间中的一个本地函数调用
(2)执行一个由操作系统直接支持的内核级的库。库的代码和数据结构存在于内核空间。调用库的一个API通常会导致对内核的系统调用。
常用线程库:POSIX Pthread Win32 Java
5.线程取消:
在线程完成之前终止线程的任务。分为异步取消(一个线程立即终止目标线程)和延迟取消(目标线程不断检查自己是否应该终止,这使其有机会以有序方式终结自己)。 Ps:要取消的线程通常称为目标线程。
6. 信号处理
作用:通知进程某个特定事件发生。
特点:由特定事件的发生所产生,产生的信号要发送到进程,一旦发送,信号必须加以处理。
处理:(1)默认信号处理程序; (2)用户定义的信号处理程序。
7.线程池:
在进程开始时创建一定数量的线程,并放入池中等待工作。当服务器收到请求时,它会唤醒池中的一个线程(如果有可以用的线程),并将要处理的请求传递给它。一旦线程完成了任务,它会返回池中再等待工作。如果池中没有可用的线程,那么服务器会一直等待直到有空线程为止。
8.线程特定数据
同属一个进程的线程共享进程数据。但在有些情况下每个线程可能需要一定数据的自己的副本,这种数据称为线程特定数据。
9.调度程序激活(解决用户线程库与内核间通信)
许多多对多or二级模型的系统在用户和内核线程之间设置一种中间数据结构(通常是轻量级进程(LWP))。for用户线程库,LWP为一种应用程序可以调度用户线程的虚拟处理器。每个LWP与内核线程相连,该内核线程被操作系统调度到物理处理器运行。若内核线程阻塞,LWP也阻塞,与LWP相连的用户线程也阻塞。
10.Linux线程
clone()创建线程
clone()被调用时,他被传递一组标志,决定父任务与子任务之间发生多少共享。
eg:将上述四个标志传递给clone(),父任务与子任务之间将共享all of the list items。
11.Pthread
1 #include<pthread.h> 2 #include<stdio.h> 3 4 int sum; 5 void* runner(void *param); 6 7 int main(int argc, char*argv[]) 8 { 9 pthread_t tid; //声明所创建的线程的标识符 10 pthread_attr_t attr; //表示线程属性 11 12 if(argc!=2){ 13 fprintf(stderr,"usage:a.out<integer value> "); 14 return -1; 15 } 16 17 if(atoi(argv[1]<0){ 18 fprintf(stderr,"%must be <=0 ",atoi(argv[1])); 19 return -1; 20 } 21 22 pthread_attr_init(&attr); //设置线程属性 23 pthread_create(&tid,&attr,runner,argv[1]); //创建一个独立线程,传递线程标识符,线程属性,函数名称,命令行参数argv[1]所提供的整数参数 24 pthread_join(tid,NULL); //父进程调用该函数,等待runner()线程的完成 25 26 printf("sum=%d ",sum); 27 } 28 29 /*/ 30 void *runner(void *param) 31 { 32 int i,upper=atoi(param); 33 sum=0; 34 35 for(i=1;i<=upper;i++) 36 sum+=i; 37 38 pthread_exit(0); //累加和线程在调用该函数之后就完成了 39 }