多线程同步与互斥机制

1、多线程并行和并发的区别

  • 并行:多个处理器或者多核处理器同时执行多个不同的任务。
  • 并发:一个处理器处理多个任务。
2、多进程之间通信方式:
  • 文件映射:本地之间
  • 共享内存:本地之间
  • 匿名管道:本地之间
  • 命名管道:跨服务器
  • 邮件槽:一对多的传输数据,通常通过网络向一台Windows机器传输
  • 剪切板:本地之间
  • socket:跨服务器
3、多线程之间通信方式:
  • 全局变量
  • 自定义消息响应
4、多线程之间同步机制:
  • 临界区:不可以跨进程,忘记解锁会无限等待,要么存在要么没有,多线程访问独占性共享资源
  • 互斥量:可以跨进程,忘记解锁会自动释放,要么存在要么没有
  • 事件:又叫线程触发器,不可以跨进程,要么存在要么没有,一个线程来唤醒另一个线程(包括自动和人工两种方式)
  • 信号量:可以跨进程,始终代表可用资源数量,当资源数为o时,线程阻塞,允许多个线程同时访问一个共享资源
5、多线程程序:
  • 多线程程序是并发执行,对于多线程的共用资源不能保证能被正确利用即不保证能被独占,并发执行的时候,哪个线程得到运行的机会是随机的也是不可预期。为了解决多线程中某个线程对资源的独占(也就是多线程同步问题),只允许一个线程拥有共享资源的独占。即多线程之间的同步机制。
6、线程:
  • 线程包括两个方面:第一:线程内核对象(OS用来存放统计信息的地方);第二:线程堆栈(函数参数和局部变量)
  • 线程在它的进程的地址空间执行代码。内核对象句柄依赖于进程而存在。
7、临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
2、互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享
3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目
4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作
  • 临界区(Critical Section):适合一个进程内的多线程访问公共区域或代码段时使用
  • 互斥量 (Mutex):适合不同进程内多线程访问公共区域或代码段时使用,与临界区相似。
  • 事件(Event):通过线程间触发事件实现同步互斥
  • 信号量(Semaphore):与临界区和互斥量不同,可以实现多个线程同时访问公共区域数据,原理与操作系统中PV操作类似,先设置一个访问公共区域的线程最大连接数,每有一个线程访问共享区资源数就减一,直到资源数小于等于零。
临界区和互斥器都有“线程所有权”的概念,所以它们是不能用来实现线程间的同步的,只能用来实现互斥。原因是由于创建临界区或互斥器的线程可以不用等待LeaveCriticalSection(),SetEvent()就可以无条件进入保护的程序段,因为它拥有这个权利。另外,互斥器可以很好的处理”遗弃“操作。若线程在未释放对向象的时候就意外终止的,其它线程可以等待到一个WAIT_ABANDONED_0。但是事件和信号量都不能做到。
事件和信号量都可以实现线程和进程间的互斥和同步。就使用效率来说,临界区的效率是最高的,因为它不是内核对象,而其它的三个都是核心对象,要借助操作系统来实现,效率相对来说就比较低。但如果要跨进程使用还是要用到互斥器、事件对象和信号量。
参考
【多线程同步与互斥机制】1、深入研究PHP及Zend Engine的线程安全模型
2、多线程同步机制的几种方法
3、多进程间通信方式和多线程同步机制总结

    推荐阅读