线程

什么是线程?                                                                                                                                                      

       是进程中的一个实体。一个进程中可以有多个线程,这些线程共享进程的所有资源,线程本身只包含一点必不可少的资源。进程开销过大。

       进程:独立地址空间,拥有PCB

       线程:也有PCB,但没有独立的地址空间(共享),可看做寄存器和栈的集合。

       区别:在于是否共享地址空间           独居(进程)  合租(线程)

       Linux下:     线程:最小的执行单位

                          进程:最小分配资源单位,可看成只有一个线程的进程

常用的概念                                                                                                                                                           

并发:在同一时刻,只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。看起来同时发生,单核。

并行:在同一时刻,有多条指令在多个处理器上同时执行。 真正的同时发生。

同步:彼此有依赖关系 的调用不应该“同时发生”,而同步就是阻止那些“同时发生”的事情。

异步:与同步相对,任何两个彼此独立的操做是异步的,它表明事情独立的发生。

信号的产生:

  1. crtl+c   ------SIGINT(终止/中断)    INT--interrupt
  2. crtl+z   ------>SIGTSTP(暂停/停止)  

        3. crtl+\    ------->SIGOUT (退出)

        硬件异常产生信号

        kill 函数/命令产生信号:

线程优缺点                                                                                                                                                           

 优点: 1.提高程序并发性  2.开销小  3.数据通信、共享数据方便

 缺点: 1.库函数,不稳定  2. 调试、编写困难、gdb不支持   3.对信号支持不好

 优点相对突出,缺点均不是硬伤。liunx下由于实现方法导致进程、线程差别不是很大。

 

 初始线程/主线程:

  1.  当C程序运行时,首先运行main函数。在线程代码中,这个特殊的执行流被称作初始线程或者主线程。可以在初始线程中做任何普通线程可以做的事情。
  2. 主线程接收参数的方式是通过argc和argv,而普通的线程只有一个参数void*(主函数main中变量(int argc,char *argv[ ])的含义,https://baike.so.com/doc/1265148-1337844.html)
  3. 主线程的特殊性在于,它在main函数返回的时候,会导致进程结束,进程内所有的线程也将会结束。可以在主线程中调用pthread_exit函数,这样进程就会等待所有线程结束时才终止。

创建线程:

  1. 主线程是随着进程的创建而创建
  2. 其他线程可以通过调用函数来创建,主要调用pthread_create
  3. 新线程可能在当前线程从函数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\n");
 8     return (void *)1;
 9 }
10 void *thread_fun2(void *arg)
11 {
12    printf("wo shi thread 2\n");
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\n");
28   }
29   printf("wo shi main thread\n");
30   printf("join1 rval is %d\n", pthread_join(tid1,&rval1));
31   //定义一级指针,需要取地址,输出返回码  0
32   printf("join2 rval is %d\n",pthread_join(tid2,&rval2));
33   printf("thread1 exit code is %d\n",(int *)rval1);//1
34   printf("thread2 exit code is %d\n",(int *)rval2);//2
35   printf("wo shi main thread\n");
36   return 0;
37 }
View Code

 

posted @ 2019-01-21 21:41  星空下聆听  阅读(166)  评论(0编辑  收藏  举报