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.等待
  • 相关阅读:
    LeetCode 109 Convert Sorted List to Binary Search Tree
    LeetCode 108 Convert Sorted Array to Binary Search Tree
    LeetCode 107. Binary Tree Level Order Traversal II
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 103 Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 104. Maximum Depth of Binary Tree
    接口和多态性
    C# 编码规范
  • 原文地址:https://www.cnblogs.com/cuckoo-/p/11444436.html
Copyright © 2011-2022 走看看