小编技术分享:线程同步基本原理与实现 大家好,我是ST。 今天主要和大家一起聊聊,线程同步的问题。
对于进程同步的问题,应该是老生常谈的话题,对于单进程来说,它不需要处理线程同步的问题,所以线程同步是在多线程环境下需要注意的一个问题。线程的主要优势在于,资源的共享性,譬如通过全局变量来实现信息共享,不过这种便捷的共享是有代价的,那就是多个线程并发访问共享数据所导致的数据不一致的问题 第一:为什么需要线程同步? 线程同步的主要目的是为了对共享资源的访问进行保护。保护的目的是为了解决数据一致性的问题。当然什么情况下才会出现数据一致性的问题,根据不同的情况进行区分;如果每个线程访问的变量都是其它线程不会读取和修改的(譬如线程函数内定义的局部变量或者只有一个线程访问的全局变量),那么就不存在数据一致性的问题;同样,如果变量是只读的,多个线程同时读取该变量也不会有数据一致性的问题;但是,当一个线程可以修改的变量,其它的线程也可以读取或者修改的时候,这个时候就存在数据一致性的问题,需要对这些线程进行同步操作,确保它们在访问变量的存储内容时不会访问到无效的值。 第二:线程中数据不一致的原因
当一个线程修改变量时,其它的线程在读取这个变量时可能会看到不一致的值,如图描述了两个 线程读写相同变量(共享变量、共享资源)的假设例子。在这个例子当中,线程 A 读取变量的值,然后再 给这个变量赋予一个新的值,但写操作需要 2 个时钟周期(这里只是假设);当线程 B 在这两个写周期中 间读取了这个变量,它就会得到不一致的值,这就出现了数据不一致的问题。
第三:线程同步代码实例 编写一个简单地代码对此文件进行测试,示例代码展示了在 2 个线程在常规方式下访 问共享资源,这里的共享资源指的就是静态全局变量 g_count。该程序创建了两个线程,且均执行同一个函 数,该函数执行一个循环,重复以下步骤:将全局变量 g_count 复制到本地变量 l_count 变量中,然后递增 l_count,再把 l_count 复制回 g_count,以此不断增加全局变量 g_count 的值。因为 l_count 是分配于线程栈 中的自动变量(函数内定义的局部变量),所以每个线程都有一份。循环重复的次数要么由命令行参数指定, 要么去默认值 1000 万次,循环结束之后线程终止,主线程回收两个线程之后,再将全局变量 g_count 的值打印出来。 代码实现情况: 第四:线程代码现象分析 编译代码,进行测试,首先执行代码,传入参数 1000,也就是让每个线程对全局变量 g_count 递增 1000 次,如下所示:
都打印结果看,得到了我们想象中的结果,每个线程递增 1000 次,最后的数值就是 2000;接着我们把 递增次数加大,采用默认值 1000 万次,如下所示:
从图中可以看出,当使用默认值得时候,输出结果错误。 第五:如何解决对共享资源的并发访问出现数据不一致的问题? 为了解决图 13.1.1 中数据不一致的问题,就得需要 Linux 提供的一些方法,也就是接下来将要向大家 介绍的线程同步技术,来实现同一时间只允许一个线程访问该变量,防止出现并发访问的情况、消除数据不一致的问题,图中描述了这种同步操作,从图中可知,线程 A 和线程 B 都不会同时访问这个变量,当 线程 A 需要修改变量的值时,必须等到写操作完成之后(不能打断它的操作),才运行线程 B 去读取。
线程的主要优势在于,资源的共享性,譬如通过全局变量来实现信息共享。不过这种便捷的共享是有代 价的,必须确保多个线程不会同时修改同一变量、或者某一线程不会读取正由其它线程修改的变量,也就是 必须确保不会出现对共享资源的并发访问。Linux 系统提供了多种用于实现线程同步的机制,常见的方法有:互斥锁、条件变量、自旋锁以及读写锁等 总结:线程同步问题在开发过程中经常遇到,掌握其中的原理,才能更好的避免发生。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/34486.html