线程概念及多线程控制

多线程:
    多进程:能够同时处理数据(并发/并行)
    多线程:能够同时处理数据(并发/并行)
        
    线程概念:
        多进程任务处理(使用的是多个虚拟地址空间):将多个任务分解为多个程序(分解到多个进程中完成)。
        多线程任务处理:多个pcb 共用同一个虚拟地址空间,同时完成一个代码段中多个不一样模块的功能。
        
        进程的理解:只有一个线程的进程
        线程的理解:
            1.在传统操做系统中进程就是一个运行中程序中的描述信息 ——>pcb,控制程序的运行
            2.linux中并无为线程设计一个tcb 来控制线程的运行
            3.在linux下线程以进程pcb 实现,也就是说,在Linux下pcb 实际是一个线程。
                (所以linux下线程:也叫轻量级进程)
                (linux下进程:实际是一个线程组——包含一个/多个线程)
            
        由于cpu 调度程序运行是调度pcb ,所以线程时cpu 调度的基本单位
        由于一个程序运行起来会分配大量资源给线程组,所以进程是资源分配的基本单位
        
        vfork 由于建立的子进程与父进程共用经过一个虚拟地址空间,所以不能同时运行
        而为何多线程不会出现这个问题?
            同一个进程的线程之间独有的数据:
                1.栈
                2.寄存器(cpu 上的硬件)
                3.errno (错误编号)
                4.信号屏蔽字(信号阻塞集合)
                5.线程id(线程标识符)
                
            同一个进程的线程之间共享的数据:
                1.数据段,代码段
                2.文件描述符表
                3.信号的处理方式
                4.工做路径
                5.用户id ,组id
                
        多线程与多进程均可以并发完成任务哪个更好?(分析优缺点,视使用场景而定)
            多线程的优势:共享同一个虚拟地址空间
                1.线程间的通信更加方便
                2.线程的建立销毁成本更低
                3.同一个进程间的线程调度成本更低
                4.执行力度更加细致
                
            多线程的缺点:
                1.缺少访问控制,健壮性低:一些系统调用或异常,针对整个进程产生效果
                
        共同优势:均可以并发/并行处理任务,提升处理效果
                
        cpu 密集程序:程序中都是大量的运算操做
        
        io 密集程序:程序中都是大量的io 操做
        
        共同缺点:对临界资源操做须要考虑更多,编码更加复杂
 
        多进程的使用场景:
            对主进程安全都要度特别高——shell(多进程的使用要比多线程安全)
            
 
    线程控制:
        线程建立:
            线程控制接口:由于操做系统并无提供直接建立一个线程的接口,就封装了一套线程接口。所以有人称
            建立的线程是一个用户态线程,在内核中对应有一个轻量级进程调度程序运行
        
            int pthread_create(pthread_t *thread, const pthread_sttr_t *attr,
                void *(*start_routine)(void *), void *arg);
                
                thread:输出型参数,用于获取新建立的线程id
                attr:线程属性一般置空
                start_routine:线程入口函数
                arg:传递给线程的参数
                返回值:成功返回0;失败返回:错误编号(errno)
            
            每个线程都有一个pcb-task——struct 都有一个pid,可是用户使用ps -ef命令查看进程的时候只有一个进程,
            也只有一个进程pid
            
            查看信息:ps -eflL | head -n 1 && ps -eflL | grep create
            
            LWP:task_struct -> pid
            PID:task_struct -> tgid(线程组id)    默认==线程组中主线程pid==进程id             
            tid:首地址(共享区中线程地址空间的首地址)
            
        线程终止:
            线程入口函数中 return, 若是在main 函数中 return 则退出整个进程
            
            void pthread_exit(void* retval) :退出调用线程 retval 通常为NULL(谁调用谁退出)
            线程退出也会造成僵尸进程,由于线程退出也要保存本身的退出返回值
            线程退出,也会保存退出返回值,而成为僵尸进程
            主线程退出,进程并不会退出。
            
            取消指定的线程:(被动推出)
            int pthread_cancel(pthread_t thread)
            thread —>
            
            课后调研:
            能不能取消本身?
            若是一个线程取消则返回值是多少?
            
        线程等待:获取指定退出线程的返回值,而且容许操做系统回收线程资源
            一个线程启动后默认右一个属性是线程处于joinable状态
            *处于joinable状态的线程,退出后,不会自动释放资源,须要被其余线程等待
            
            int pthread_join(pthread_t thread, void **retval);
            功能:等待线程退出,获取返回值,回收线程资源
            前提:这个等待的线程必须处于joinable状态
            pthread-> 指定的线程id
            retval-> 获取线程的退出返回值
            返回值
                成功:0  失败:错误编号(errno)
            
        
        线程分离:(设置线程的属性从 joinable 变成 detach 属性)
            功能:分离一个线程,线程退出后系统将自动回收资源,被分离的线程没法被等待,如果非要pthread_join则会报错返回
            
            int pthread_detach(pthread_t thread);->能够在任意位置调用
            thread:要被分离的线程id
            
            注意:线程被分离的前提是用户不关心线程的退出返回值
            *处于detach状态的线程退出后自动回收资源,不须要被等待
            
            *线程默认的属性是joinable
相关文章
相关标签/搜索