什么是线程?
是进程中的一个实体。一个进程中可以有多个线程,这些线程共享进程的所有资源,线程本身只包含一点必不可少的资源。进程开销过大。
进程:独立地址空间,拥有PCB
线程:也有PCB,但没有独立的地址空间(共享),可看做寄存器和栈的集合。
区别:在于是否共享地址空间 独居(进程) 合租(线程)
Linux下: 线程:最小的执行单位
进程:最小分配资源单位,可看成只有一个线程的进程
常用的概念
并发:在同一时刻,只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。看起来同时发生,单核。
并行:在同一时刻,有多条指令在多个处理器上同时执行。 真正的同时发生。
同步:彼此有依赖关系 的调用不应该“同时发生”,而同步就是阻止那些“同时发生”的事情。
异步:与同步相对,任何两个彼此独立的操做是异步的,它表明事情独立的发生。
信号的产生:
- crtl+c ------SIGINT(终止/中断) INT--interrupt
- crtl+z ------>SIGTSTP(暂停/停止)
3. crtl+ ------->SIGOUT (退出)
硬件异常产生信号
kill 函数/命令产生信号:
线程优缺点
优点: 1.提高程序并发性 2.开销小 3.数据通信、共享数据方便
缺点: 1.库函数,不稳定 2. 调试、编写困难、gdb不支持 3.对信号支持不好
优点相对突出,缺点均不是硬伤。liunx下由于实现方法导致进程、线程差别不是很大。
初始线程/主线程:
- 当C程序运行时,首先运行main函数。在线程代码中,这个特殊的执行流被称作初始线程或者主线程。可以在初始线程中做任何普通线程可以做的事情。
- 主线程接收参数的方式是通过argc和argv,而普通的线程只有一个参数void*(主函数main中变量(int argc,char *argv[ ])的含义,https://baike.so.com/doc/1265148-1337844.html)
- 主线程的特殊性在于,它在main函数返回的时候,会导致进程结束,进程内所有的线程也将会结束。可以在主线程中调用pthread_exit函数,这样进程就会等待所有线程结束时才终止。
创建线程:
- 主线程是随着进程的创建而创建
- 其他线程可以通过调用函数来创建,主要调用pthread_create
- 新线程可能在当前线程从函数pthread_create返回之前就已经运行了,甚至新线程可能在当前线程函数pthread_create返回之前就已经运行完毕了。
线程退出
如果进程中的任意一个线程调用了exit , _Exit,_exit,那么整个进程就会终止
将单个线程退出 void pthread_exit(void *retval);
参数:retval 表示线程退出状态。
等待线程结束和线程分离
函数:int pthread_join(pthread_t thread,void **retval) 参数:thread:线程ID(注意:不是指针) retval:存储线程结束状态 功能:阻塞等待线程退出,获取线程退出状态。相当于进程waitpid()函数 进程中:main返回值、exit参数-->int;等待子进程结束wait函数参数-->int * 线程中:线程主函数返回值、pthread_exit-->void*;等待线程结束pthread_join函数参 数-->void**
函数:int pthread_detach(pthread_t thread) 返回值:成功0;失败:错误号 功能:实现线程分离
线程分离状态:指定该状态,线程主动与主控线程断开关系,线程结束后,其退出状态不由其他线程获取,而直接自己自动释放。网络,多线程服务器常用。
进程若有该机制,将不会产生僵尸进程。僵尸进程的产生主要由于进程死后,大部分资源被释放。一点残留资源扔存在于系统中
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<pthread.h> 4 #include<errno.h> 5 void *thread_fun1(void *arg) 6 { 7 printf("wo shi thread 1 "); 8 return (void *)1; 9 } 10 void *thread_fun2(void *arg) 11 { 12 printf("wo shi thread 2 "); 13 pthread_detach(pthread_self());//加上它返回码退出码错误 14 pthread_exit((void *)2); 15 } 16 int main() 17 { 18 int err1,err2; 19 pthread_t tid1,tid2; 20 void *rval1,*rval2;// 空指针 21 22 err1=pthread_create(&tid1,NULL,thread_fun1,NULL); 23 err2=pthread_create(&tid2,NULL,thread_fun2,NULL); 24 25 if(err1||err2)//创建失败 26 { 27 printf("create new thread failed "); 28 } 29 printf("wo shi main thread "); 30 printf("join1 rval is %d ", pthread_join(tid1,&rval1)); 31 //定义一级指针,需要取地址,输出返回码 0 32 printf("join2 rval is %d ",pthread_join(tid2,&rval2)); 33 printf("thread1 exit code is %d ",(int *)rval1);//1 34 printf("thread2 exit code is %d ",(int *)rval2);//2 35 printf("wo shi main thread "); 36 return 0; 37 }