为什么我们需要线程同步?
多线程程序中,各线程可以理解为同时在执行(尽管在单处理器的
系统中并不是真的在同时运行,但是表现出的现象是在同时运行,即使在多处理器的系统中也并不是任何时候多个线程同时在运行),我们不知道哪个线程哪个时间运行到了哪个地方,这受机器与操作系统的影响,在一些场合,我们必须要对线程的运行情况有所控制,使它们可以协同的工作。
例如在一个银行的系统中,当一个用户在取钱的时候,另一个帐户在向这个
帐号里 存钱,结果会怎么样呢,如果存款的线程在读取了当前金额后,完成操作前,取钱业务的线程把钱取走,接着存钱业务的线程把在以前的金额基础上加上存钱的数额 存入了数据库,也许这正是你所期望的,因为你白白的拿到了一笔钱,但这显然不是这个业务系统的所有者银行所想要看到的,怎么来解决这个问题呢?这样也许可 以:银行在一个收到一个业务请求后,把这个帐号临时的锁定起来,等当前业务结束后,其它的业务请求才会被受理,这样就不存在前边的情况,银行就避免了损 失。
在一个信息采集系统中,一个中心处理计算机,数个传感器。当由传感器传回数据后,传感器的控制电路要根据计算机的分析来决定下一步的采集参数等。而计算机 的分析由需要对所有传感器的数据进行统计分析才能完成,而各传感器发回数据的速率并不一定是同步的,特别是当传感器分布比较分散时,此时,我们就面临着一 个同步的问题,对于这个问题,我们可以在每一个数据到达后判断是否所有数据都已传回,如果没有,则将些请求暂时挂起,等待下一个传回的数据,如果仍然不是 最后一个数据,仍然挂起,依此类推,当最后一组宝贵的数据终于到达时,通知所有挂起的线程,OK了,你可以继续了。这样就解决了这样一个难题。
另一种场景资源调度问题。在一个并行系统中,系统中每一项资源都不止一份,但是一个资源只能有一个控制方(独享资源),我们的目标是让系统既可以快速的访 问到所请求的资源,又要保证不出现冲突,这中间也会出现问题,有了上面两个问题的分析,我想你应该已经有这个问题的答案了吧。
线程同步中的一些问题与思考
线程同步有一个很重要的问题是线程死锁,如果我们现在有三个线程(A,B,C)要实现同步,如果在某种情况下,A在等B,B要等C,而此时C却在等A…… 问题出现了,很显然,ABC都不会运行。这种现象叫死锁(在写这篇文章的时候我曾试图写上了一个例子,但是当我自己再来读的时候都有些晕,为了不让别人对 这部分产生恐惧情绪,最后就给删了,其实这个不复杂,只是想找个具体的例子的时候不太容易表述。)这种情况在我们的程序中是不允许出现的,这种无限的等待 是没有意义的,只会给人你的程序死掉了的感觉。
有人认为线程同步所引发的等待对性能来讲代价太高,其实线程同步所带来的性能损失是微不足道的,当你试图用其它的方案来解决同样的问题的时候,你会发现你 必须把工作过程序列化,让多线程的问题在一个工作流程上解决,这在多处理器系统,或是分布式系统中将是对系统资源的极大浪费,对于一个追求效率的开发人员 来讲这简直就是犯罪,即使在单处理器的
环境中,也会有更大的时间开支,要知道计算机的计算要比人的输入操作快的多!
线程同步,是在多线程编程中的关键问题,如果可以很好的解决这个问题,你的系统就可以安全稳定高效的运作。
下一次我们将讨论线程同步的
C语言实现(仍然是基于Pthread库)
补充:Pthread属于POSIX,因此可以在任何POSIX系统上使用(几乎所有的UNIX,
Linux(似乎还有MacOSX,因为我曾见过Apple的
软件使用了Pthread,应该在MacOSX上也有,这样才好移植)系统实现了POSIX,POSIX的部分接口也在Windows上有实现,所以我
推荐使用Pthread
相关文章
- 基于C语言的面向对象编程
- 网络编程:基于C语言的简易代理服务器实现(proxylab)
- C#实现异步编程的两个简单机制(异步委托&定时器)及Thread实现多线程
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介
- socket 网络编程快速入门(二)教你编写基于UDP/TCP的服务端多线程通信
- C++11中多线程编程-std::async的深入讲解
- 基于C API的MySQL数据库多线程访问方法
- 浅谈Java多线程编程中Boolean常量的同步问题
- C#中的并行与多线程编程
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)