zoukankan      html  css  js  c++  java
  • linux多线程编程2-线程同步

    1、线程同步的概念:这里说的同步并非时同时的概念,而是指协同、协助、互相配合,即按照一定的次序完成需要的动作,使程序正常运行。所谓的线程同步,指的是一个线程某个功能调用时,没有得到结果之前,该调用不返回,同时其他线程为保证数据一致性,不能调用该功能。

    2、互斥量:两个线程访问同一块资源,如果不协调顺序,容易造成数据混乱,这时候,就需要加上一把锁。例如,只有一个厕所,a先进去,为了防止下一个人进来,他就先把厕所门给锁住,等自己拉完过后再将门打开,这时候即释放了锁,下一个人就可以进去,再上锁,以此重复。

      mutex

      锁的初始化:int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

            pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

            其中 restrict 代表强制使用mutex这个结构进行初始化,初始化锁有两种方式,一种是定义一个pthread_mutex_t 变量,之后调用init函数进行初始化,属性一般传NULL; 另一种就是通过宏进行初始化,即通过pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER来初始化一个全局锁。

      摧毁锁: int pthread_mutex_destroy(pthread_mutex_t *mutex);

      加锁:int pthread_mutex_lock(pthread_mutex_t *mutex);

         如果该锁已经被占用,此时,会陷入阻塞等待状态。

         int pthread_mutex_trylock(pthread_mutex_t *mutex);

         如果该锁被占用,则会返回一个errnum,可以通过调用strerror(errnum)来获取错误信息。

      解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);

    3、死锁:死锁一般有两种情况。

        第一种是已经给上了一把锁,这时候你忘记你已经上了一把锁,这时候你又上了一把锁,这时候就会陷入阻塞等待状态,或者是又上了另一把锁,这时候其他线程要加锁时,也会因为原来的锁没释放,陷入阻塞等待状态;

        第二种是交叉锁,比如线程a和线程b同时拥有两把锁才能进行任务执行,这时候a拿到锁1,b拿到锁2,a需要继续拿到锁2才能只能,b需要拿到锁1才能执行,这时候,a和b就都会陷入阻塞等待状态,产生死锁。

        解决的办法就是合理分配锁,避免死锁产生。

     4、读写锁:假如有一块共享资源,多个线程同时进行读数据的操作,这时候如果加正常的锁,必然会大大地浪费时间,因为数据本身不会变化;而进行写操作的时候,就不能有其他操作同时访问或者修改该共享资源的数据,这时候,就诞生的一种读写锁来满足这种需求。

        读写锁特点:读共享、写独占、写的优先级高;

        读写锁初始化int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

               pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

        读写锁销毁:int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

        读锁int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);阻塞

           int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);非阻塞

        写锁int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);非阻塞

           int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);阻塞

        释放锁:int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

  • 相关阅读:
    亮剑.NET的系列文章之ADO.NET五大类(二)
    Effective C++ 读书笔记之Part6.Inheritance and ObjectOriented Design
    论计算机专业毕业生的人文素养
    LLVM每日谈之十四 如何给Clang添加一个属性
    那些年,面试中遇到的那些奇葩们
    亮剑.NET的系列文章之.NET实现三层架构(三)
    [转]C++预编译头文件
    [转]文件间的编译依赖性
    [转]详解编译预处理
    [转]Visual Studio 2005 IDE 技巧和窍门
  • 原文地址:https://www.cnblogs.com/zz1314/p/12873553.html
Copyright © 2011-2022 走看看