欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > linux >内容正文

linux

Linux学习之系统编程篇:线程同步的引出和思想

发布时间:2024/9/30 linux 41 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Linux学习之系统编程篇:线程同步的引出和思想 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一、线程同步的引出

程序:父子线程交替数数

#include <stdio.h> #include <unistd.h> #include <string.h> #include <pthread.h> #define MAX 10000 //定义全局变量 int num = 0; void *func_a(void *arg) {for(int i = 0; i < MAX; i++){int cur = num;cur++;num = cur;printf("Thread A ,id = %lu, num = %d\n",pthread_self(), num);usleep(10);}return NULL; } void *func_b(void *arg) {for(int i = 0; i < MAX; i++){int cur = num;cur++;num = cur;printf("Thread B ,id = %lu, num = %d\n",pthread_self(), num);usleep(10);}return NULL; } int main() {pthread_t p1, p2;//创建两个子线程pthread_create(&p1, NULL, func_a, NULL);pthread_create(&p2, NULL, func_b, NULL);//阻塞回收资源pthread_join(p1, NULL);pthread_join(p2, NULL);return 0; }

注意:
本意:AB 线程各加 10000 次,最终应该 num = 20000
但事实上 num < 20000,意味着有 BUG。
bug 由来:
得到 num 值分 2 步:
第一步,进行加运算;
第二步,加后的 num 存入内存(存入内存,num 的值才能被输出到屏幕)
(1)某时 num= x A 占用 CPU,加了 20 次,存入 CPU 的寄存器中,还没来得及存入内存,就失去 CPU。
(2)此时 B 占用 CUP,A num 没存入内存,所以 num 还是 x ,加了 30 次,存入内存,num=x+30,此时 A 又占用 CPU。
(3)A 继续执行未完成的动作,将原先 x+20 的结果,存入内存,原 num=x+30 被覆盖,变成 x+20,A 失去 CPU。
(4)B 继续执行,本来应该从 x+30 开始,但却从 x+20,因此丢失 10 个数据。
这种现象成为数据混乱,产生数据混乱的原因:
(1)有多个线程操作共享数据。
(2)CPU 的调度问题。
解决数据混乱的方法:线程同步即协同步调,按照先后顺序执行操作,按上例来讲,就说彻底完成 2 步后,才可以失去CPU,如果没有彻底完成,其他线程只能等待。

二、线程同步思想

(1)先给共享资源加锁。
(2)线程 1 要访问共享资源,首先判断锁是打开还是锁着的
如果是锁着的则线程阻塞(阻塞在这把锁代码上)或者直接返回。如果是开的那么先把锁锁上(这样其他线程就被阻塞在外面了),线程 1 访问共享资源。
(3)线程 1 访问共享资源结束:将锁解锁。
(4)其他线程继续抢锁,抢到后,上锁,访问共享资源,访问结束后,解锁 ……
注意:本来多线程访问共享资源时候,可以并行,通过加锁机制,并行变串行,好处是数据不会混乱,但效率会变低。

总结

以上是生活随笔为你收集整理的Linux学习之系统编程篇:线程同步的引出和思想的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。