当前位置: 首页 > wzjs >正文

客服平台系统网络优化主要做什么

客服平台系统,网络优化主要做什么,成都企业网站排名优化,企业建设网站的比例一、多线程对共享变量的非互斥访问 我们将要做的&#xff1a;构造多线程共享变量竞争的案例&#xff0c;并分析现象发生的原因&#xff0c;进而思考解决方式。 案例源代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <pthread.h> #inc…

一、多线程对共享变量的非互斥访问

我们将要做的:构造多线程共享变量竞争的案例,并分析现象发生的原因,进而思考解决方式。

案例源代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>int num=30,count=10;void *sub1(void *arg) {int i = 0,tmp;for (; i <count; i++){tmp=num-1;usleep(13);num=tmp;printf("线程1 num减1后值为: %d\n",num);}return ((void *)0);
}
void *sub2(void *arg){int i=0,tmp;for(;i<count;i++){tmp=num-1;usleep(31);num=tmp;printf("线程2 num减1后值为: %d\n",num);}return ((void *)0);
}
int main(int argc, char** argv) {pthread_t tid1,tid2; // 两个子线程的idint err,i=0,tmp;void *tret; // 线程返回值err=pthread_create(&tid1,NULL,sub1,NULL);if(err!=0){printf("pthread_create error:%s\n",strerror(err));exit(-1);}err=pthread_create(&tid2,NULL,sub2,NULL);if(err!=0){printf("pthread_create error:%s\n",strerror(err));exit(-1);}for(;i<count;i++){tmp=num-1;usleep(5);num=tmp;printf("main num减1后值为: %d\n",num);}printf("两个线程运行结束\n");err=pthread_join(tid1,&tret);if(err!=0){printf("can not join with thread1:%s\n",strerror(err));exit(-1);}printf("thread 1 exit code %d\n",(int)tret);err=pthread_join(tid2,&tret);if(err!=0){printf("can not join with thread1:%s\n",strerror(err));exit(-1);}printf("thread 2 exit code %d\n",(int)tret);return 0;
}

🧠 1. 程序功能概述

创建了两个线程 sub1sub2,以及主线程三者共同对一个全局变量 num 执行减 1 操作,共减去 count * 3 = 30 次。

初始值:

int num = 30, count = 10;

所以理论上最终 num == 0,但实际上并不一定!


⚠️ 2. 存在的核心问题:数据竞争(Race Condition)

❗ 对 num-- 是分三步执行的:
tmp = num - 1;
usleep(x);
num = tmp;

这个过程不是原子操作,多个线程可能“交叉”访问这个变量,造成竞态条件(Race Condition)

中间插入 usleep() 只是为了放大并发写入带来的冲突概率,模拟真实环境下的并发问题。

举例说明:

假设此时 num = 10,两个线程同时读到:

线程1:tmp1 = 10 - 1 = 9,睡眠
线程2:tmp2 = 10 - 1 = 9,睡眠

然后:

线程1醒来执行 num = 9
线程2醒来执行 num = 9 (覆盖了线程1的操作)

🔴 这样 num 实际只减少了一次,而我们期望它减少两次(一个线程分别减少一次)!


🔍 3. 运行效果举例(输出可能类似):

线程1 num减1后值为: 29
线程2 num减1后值为: 28
main num减1后值为: 27
线程1 num减1后值为: 27  ←❗ 重复了
main num减1后值为: 26
线程2 num减1后值为: 26  ←❗ 再次重复

最终 num 的值可能 不是 0,甚至是更高。原因就是上面说的:很多次减法操作失效了。


✅4. 如何解决?使用线程同步机制:互斥锁 pthread_mutex_t

例如,添加全局互斥锁

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

将每个对 num 的访问部分用锁保护:

pthread_mutex_lock(&lock);
tmp = num - 1;
usleep(13); // 保留你原来的模拟处理
num = tmp;
pthread_mutex_unlock(&lock);

🔒 这样确保每次只有一个线程在访问和修改 num


🛠️ 5. 修改后关键片段示例(以 sub1 为例)

void *sub1(void *arg) {int i = 0, tmp;for (; i < count; i++) {pthread_mutex_lock(&lock);tmp = num - 1;usleep(13);num = tmp;printf("线程1 num减1后值为: %d\n", num);pthread_mutex_unlock(&lock);}return ((void *)0);
}

主线程、sub2 中也要加锁。


🔚 6. 总结

问题说明
数据竞争多线程访问全局变量未加锁
后果num 最终值不确定,减法丢失
解决使用 pthread_mutex 互斥锁
调试建议加 -fsanitize=thread 或使用 valgrind --tool=helgrind 检查

二、并发线程同步与互斥

本次案例是在前一个案例「多线程对共享变量的非互斥访问」的基础上进行了修复和优化,引入了 pthread_mutex 互斥锁机制,实现了 多线程对共享变量的互斥访问控制,有效解决了数据竞争问题。

案例源代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
int num=30, count=10;
pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;
void *sub1(void *arg) {int i = 0,tmp;for (; i<count; i++){pthread_mutex_lock(&mylock);   // 上锁		tmp=num-1;usleep(13);num=tmp;pthread_mutex_unlock(&mylock); // 解锁	printf("线程1  第「%d」次num减1后值为: %d\n",i+1,num);}return ((void *)0);
}
void *sub2(void *arg){int i=0,tmp;for(;i<count;i++){pthread_mutex_lock(&mylock); // 上锁tmp=num-1;usleep(31);num=tmp;pthread_mutex_unlock(&mylock); // 解锁printf("线程2  第「%d」次num减1后值为: %d\n",i+1,num);}return ((void *)0);
}
int main(int argc, char** argv) {pthread_t tid1,tid2;int err,i=0,tmp;void *tret; // 线程返回值err=pthread_create(&tid1,NULL,sub1,NULL);if(err!=0){printf("pthread_create error:%s\n",strerror(err));exit(-1);}err=pthread_create(&tid2,NULL,sub2,NULL);if(err!=0){printf("pthread_create error:%s\n",strerror(err));exit(-1);}for(;i<count;i++){pthread_mutex_lock(&mylock); // 主线程上锁tmp=num-1;usleep(5); // num=tmp;		pthread_mutex_unlock(&mylock); // 主线程释放锁printf("主线程 第「%d」次num减1后值为: %d\n",i+1,num);}printf("两个线程运行结束\n");err=pthread_join(tid1,&tret);if(err!=0){printf("can not join with thread1:%s\n",strerror(err));exit(-1);}printf("thread 1 exit code %d\n",(int)tret);err=pthread_join(tid2,&tret);if(err!=0){printf("can not join with thread1:%s\n",strerror(err));exit(-1);}printf("thread 2 exit code %d\n",(int)tret);return 0;
}

下面从结构和功能两个维度逐段讲解这段代码。


✅ 1. 程序功能概述

多线程同时对一个共享变量 num 进行减 1 操作,为避免多个线程同时访问导致的数据错误,使用 互斥锁 pthread_mutex_t 实现同步,确保线程间的安全访问。


🔧 2. 头文件说明

#include <stdio.h>      // printf()
#include <stdlib.h>     // exit()
#include <pthread.h>    // pthread_create, pthread_join, pthread_mutex_*
#include <unistd.h>     // usleep()
#include <string.h>     // strerror()

✅ 上述头文件提供了线程创建、同步、休眠和错误信息处理等功能。


🔐 3. 全局变量及互斥锁

int num=30, count=10;
pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
  • num: 被所有线程共享的变量,初始为 30。
  • count: 每个线程循环次数。
  • mylock: 全局互斥锁,用于防止多个线程同时修改 num

🧵 4. 线程函数 sub1 和 sub2

🔹 sub1 函数
void *sub1(void *arg) {int i = 0, tmp;for (; i < count; i++) {pthread_mutex_lock(&mylock);      // 上锁tmp = num - 1;usleep(13);                       // 模拟计算耗时num = tmp;pthread_mutex_unlock(&mylock);    // 解锁printf("线程1 第【%d】num减1后值为: %d\n", i, num);}return ((void *)0);
}
🔹 sub2 函数
void *sub2(void *arg) {int i = 0, tmp;for (; i < count; i++) {pthread_mutex_lock(&mylock);tmp = num - 1;usleep(31);num = tmp;pthread_mutex_unlock(&mylock);printf("线程2 第【%d】num减1后值为: %d\n", i, num);}return ((void *)0);
}

🟡 共同点:

  • 都对共享变量 num 执行减 1 操作。
  • 每次操作前后都加了互斥锁,保证了对 num 的访问是互斥的。

🟡 不同点:

  • 睡眠时间不同,用于模拟线程调度差异,放大并发现象。

👑 5. 主线程 main 函数

1️⃣ 创建线程
pthread_create(&tid1, NULL, sub1, NULL);
pthread_create(&tid2, NULL, sub2, NULL);
  • 启动两个子线程 sub1sub2,它们会与主线程并发执行。

2️⃣ 主线程也参与对 num 的操作
for (; i < count; i++) {pthread_mutex_lock(&mylock);tmp = num - 1;usleep(5);num = tmp;pthread_mutex_unlock(&mylock);printf("main 第【%d】num减1后值为: %d\n", i, num);
}

💡 主线程和子线程一样,每次操作都加锁保护,保证不会同时操作 num,从而避免数据冲突


3️⃣ 等待线程结束并获取退出状态
pthread_join(tid1, &tret);
pthread_join(tid2, &tret);
  • 使用 pthread_join() 等待线程结束。
  • 线程的返回值是 NULL(即 return ((void*)0)),打印时结果是 0

🧪 6. 运行效果示例(输出节选)

主线程 第「1」次num减1后值为: 29
主线程 第「2」次num减1后值为: 28
主线程 第「3」次num减1后值为: 27
线程1  第「1」次num减1后值为: 26
线程1  第「2」次num减1后值为: 25
...

最终:

两个线程运行结束
thread 1 exit code 0
thread 2 exit code 0

🔒 7. 为什么这次没有竞态条件?

因为你加入了 pthread_mutex_lock()pthread_mutex_unlock() 对每一次对 num 的读-改-写操作进行了加锁保护,确保每次修改都是互斥的、完整的


📌 八、总结

项目说明
多线程创建使用 pthread_create 创建两个线程
共享资源所有线程和主线程共享变量 num
数据保护使用 pthread_mutex 实现访问同步,防止竞态
同步结束使用 pthread_join 等待子线程结束
延时模拟使用 usleep() 模拟并发中的调度差异
http://www.dtcms.com/wzjs/74843.html

相关文章:

  • 专业地推团队鹤壁seo推广
  • 单位服务器网站打不开做一个网站的步骤
  • 网站建设越来越注重用户体验免费关键词挖掘工具
  • 网站开发总跳转至404页面发布外链的步骤
  • 乌鲁木齐网站制作公司可靠吗河南企业网站建设
  • 天津建设网网站打不开网络营销比较好的企业
  • 榆林高端网站建设如何设计网站建设优化的技巧
  • 做平面设计的网站哈尔滨网络优化公司有哪些
  • 如何做一个个人做网站阿里指数在线查询
  • 东莞网站建设属于什么专业给公司做网站的公司
  • 做海外市场什么网站推广seo类目链接优化
  • 创新的成都 网站建设长沙seo搜索
  • 郴州做网站营销软件有哪些
  • 动态网站建设与管理域名注册需要多少钱
  • 网站水印怎么做的网站查询器
  • 网站做seo的好处游戏推广赚钱
  • 珠海网站建设公司怎样打百度人工客服热线
  • 知名网站建设是哪家便宜推广普通话手抄报内容怎么写
  • 购物平台排名淘宝seo软件
  • 做网站赌博的推广是不是犯罪的短视频培训课程
  • b2c平台网站成都搜索优化整站优化
  • wap手机网站代码百度资源搜索
  • 如何做一个网站代码网络营销的推广手段
  • wordpress免费企业青岛官网优化
  • 山东建设工程执业证书查询网站广告投放平台有哪些
  • 没有公司网站如何做推广优化seo软件
  • 网站备案连接怎么做如何让百度收录
  • 网站建设 中企动力医院重庆网站建设与制作
  • 网站建设市场行情报价百度推广后台登录入口
  • 网站域名备案和icp备案一样么网页设计与制作代码成品