基于C语言的多线程编程 线程同步

时间:2021-11-16 18:35:43
为什么我们需要线程同步?

多线程程序中,各线程可以理解为同时在执行(尽管在单处理器的 系统中并不是真的在同时运行,但是表现出的现象是在同时运行,即使在多处理器的系统中也并不是任何时候多个线程同时在运行),我们不知道哪个线程哪个时间运行到了哪个地方,这受机器与操作系统的影响,在一些场合,我们必须要对线程的运行情况有所控制,使它们可以协同的工作。

例如在一个银行的系统中,当一个用户在取钱的时候,另一个帐户在向这个 帐号里 存钱,结果会怎么样呢,如果存款的线程在读取了当前金额后,完成操作前,取钱业务的线程把钱取走,接着存钱业务的线程把在以前的金额基础上加上存钱的数额 存入了数据库,也许这正是你所期望的,因为你白白的拿到了一笔钱,但这显然不是这个业务系统的所有者银行所想要看到的,怎么来解决这个问题呢?这样也许可 以:银行在一个收到一个业务请求后,把这个帐号临时的锁定起来,等当前业务结束后,其它的业务请求才会被受理,这样就不存在前边的情况,银行就避免了损 失。

在一个信息采集系统中,一个中心处理计算机,数个传感器。当由传感器传回数据后,传感器的控制电路要根据计算机的分析来决定下一步的采集参数等。而计算机 的分析由需要对所有传感器的数据进行统计分析才能完成,而各传感器发回数据的速率并不一定是同步的,特别是当传感器分布比较分散时,此时,我们就面临着一 个同步的问题,对于这个问题,我们可以在每一个数据到达后判断是否所有数据都已传回,如果没有,则将些请求暂时挂起,等待下一个传回的数据,如果仍然不是 最后一个数据,仍然挂起,依此类推,当最后一组宝贵的数据终于到达时,通知所有挂起的线程,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