线程:一个进程内部的控制序列
并发:一个CPU多个进程
并行:CPU足够多,一个进程可以分配一个CPU,可以同时运行
linux中用进程来模拟线程,即轻量级进程
cpu调度时以PCB为基本单位的
我们所说的进程是具有一个或多个执行流的线程组(即所有PCB组成的线程组)
进程与线程的区别:
- 进程是操作系统分配资源的基本单位线程是CPU调度的基本单位
- 进程有自己独立的地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段。而线程是共享进程的虚拟地址空间。
- 线程之间通信更方便,同一进程下的线程共享全局变量、静态变量等数据。而进程之间的通信需要以通信的方式进程
- 多进程程序更健壮,多线程程序只要有一个进程死掉,整个进程就死掉了。
线程私有:线程ID、栈、一组寄存器、errno(全局变量 错误原因)、信号屏蔽字(block信号集)、调度优先级
线程共有:虚拟地址空间、文件描述符表(结构体数组的下标)、信号的处理方式、用户id和组id、当前工作目录
线程的优缺点:
优点:
1.线程创建和销毁的成本相较于进程更低,执行粒度更细
2.线程的切换成本想对于进程更低,因为它可能在同一进程内进行切换不用跨页表跨虚拟地址空间
3.线程占用的资源比进程少很多
4.在等待慢速I/O操作结束的同时,程序可以执行其他的计算任务
缺点:
1.线程启动过多时,CPU资源不够用,这样调度切换频繁,耗费时间
2.健壮性降低,在一个线程程序里因为时间分配上的偏差或者因共享了不该共享的变量而造成不良影响的可能性很大。
3.缺乏访问控制,线程中调用OS函数会对整个进程造成影响,如exit这个退出进程的函数在线程中调用时,会造成该进程中其他线程也被退出
4.编程难度提高
线程的创建:
头文件:#include<pthread.h>
创建线程(在内核内部完成):
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*start_routine)(void*),void*arg);
pthread_t 时无符号长整型,用%lu打印
thread:获取线程id
attr:线程属性参数,包括线程继承性、堆栈大小等等,一般写NULL
*start_routine:函数指针,告诉线程运行哪个函数
arg:往void *中传入参数
成功返回0错误返回错误编号
具体代码:
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<pthread.h>
5 void loop1()
6 {
7 while(1)
8 {
9 printf("this is pthread 1\n");
10 sleep(1);
11 }
12 }
13 void loop2()
14 {
15 while(1)
16 {
17 printf("this is pthread 2\n");
18 sleep(1);
19 }
20 }
21 void *thr_start(void *arg)
22 {
23 loop1();
24 return NULL;
25 }
26 int main()
27 {
28 pthread_t tid;
29 int ret=pthread_create(&tid,NULL,thr_start,NULL);
30 if(ret!=0)
31 {
32 printf("create error:%s\n",strerror(ret));
33 return -1;
34 }
35 loop2();
36 }
注意!!:编译和连接时需要加入-pthread