zoukankan      html  css  js  c++  java
  • 线程安全

        线程安全
            
            可重入/不可重入:针对函数,多个执行流中是否可以同时进入函数运行而不出现问题
            
            概念:指多个线程同时处理操作临界资源而不会出现数据二义性,则称是线程安全的            
                二义性:在线程中是否对临界资源进行了非原子操作
     
            如何实现线程安全:    
                同步(保证合理):临界资源的合理访问(时序可控)        
                互斥(保证安全):临界资源同一时间唯一访问
                    
                    如何实现互斥:(首先自身是安全的)
                        互斥锁:(黄牛抢票程序)
                            使用一个0/1的原子操作的计数器(图片):
                                1 -> 表示可以加锁,加锁就是计数-1 .
                                操作完毕后要解锁,解锁就是计数+1
                                0 -> 表示不可以加锁,不能加锁则等待
                                
                            操作步骤:
                                1.定义互斥锁变量    
                                    pthread_mutex_t mutex;
                                2.初始化互斥锁变量    
                                    int pthread_mutex_init()
                                3.加锁/解锁--->要在临界资源访问之前进行            
                                    阻塞加锁,加不上锁就阻塞:
                                        int pthread_mutex_lock()
                                    
                                    非阻塞加锁,加不上则直接报错返回:                                    
                                        int pthread_mutex_trylock()
                                
                                    限时阻塞加锁:
                                        int pthread_mutex_timedlock()
                                    
                                    *加锁之后要在线程任意有可能退出的地方解锁
                                    
                                    解锁:
                                        int pthread_mutex_unlock()
                            
                                4.销毁互斥锁        
                                    int pthread_mutex_destroy()
                            
                        死锁:(在多个锁的使用时,在对加锁的推进顺序使用不当的造成)
                            因为对一些无法加锁的锁进行加锁,而导致程序卡死
                                
                        产生场景:
                                1.加锁/解锁的顺序不同
                            ** 2....
                            
                        **死锁产生的必要条件:
                            1.互斥条件(我操作的时候别人的能操作)
                            2.不可剥夺条件(我的锁,别人不能解)
                            3.请求与保持条件(拿着手里的,请求其他的,其他的不能请求到,手里的也不放)
                            4.环路等待条件(3)
     
                        如何预防死锁:破坏死锁产生的必要条件
                            
                        **避免死锁:
                            1.死锁检测算法
                            2.银行家算法                        
                    
                    如何实现同步:临界资源访问的合理性——生产出来才能使用——等待加唤醒
                        没有资源则等待(这是一种死等),生产资源后唤醒等待
                        
                        线程1如果操作条件满足,则操作,否则进行等待
                        线程2促进条件满足,唤醒等待的线程
                        
                        条件变量:
                            1.定义一个条件变量
                                pthread_cond_t    
                            2.初始化条件变量
                                int pthread_cond_init()
                            3.等待/唤醒
                                死等待:
                                    int pthread_cond_wait()//先解锁在等待,使用原子操作保证安全
                                    ——集合了解锁后挂起的操作(原子操作),有可能还又没来得及挂起就已经有人唤醒——则导致白唤醒,
                                    因为含有临界资源,就必须加锁保护
                                    
                                    此操作共包含了3个操作:
                                        1.解锁        2.休眠        3.被唤醒后加锁
                                    
                                限时等待,超时后则返回:
                                    int pthread_cond_timedwait()
                                
                                
                                广播唤醒:(唤醒等待的人所有人)
                                    int pthread_cond_broadcast()
                                    
                                唤醒至少一个等待的人:
                                    int pthread_cond_signal()
                                    
                            4.销毁条件变量
                                int pthread_cond_destroy()
                        
                        条件变量为什么要搭配互斥锁使用:
                            因为条件变量本身只提供等待与唤醒的功能,因此具体什么时候的等待需要
                            用户来进行判断,这个条件的判断,通常涉及临界资源的操作(其他线程要通过修改文件,来促使条件满足)    
                            而这个临界资源二点操作应该受保护,因此搭配互斥锁使用。
                            
                        加锁:
                            条件判断-不满足
                                1.解锁
                                2.等待
  • 相关阅读:
    elk 搭建
    Web 开发规范 — WSGI
    Web 开发规范 — WSGI
    fastjson生成和解析json数据,序列化和反序列化数据
    第四章 字典
    Struts2 无后缀action请求
    字典和列表访问方式:
    第3章 使用字符串
    Struts2中的ModelDriven机制及其运用
    Struts2 的Action中取得请求参数值的几种方法
  • 原文地址:https://www.cnblogs.com/cuckoo-/p/11444436.html
Copyright © 2011-2022 走看看