线程同步
线程的主要优势在于,能够通过全局变量来共享信息。必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正由
其他线程修改的变量。临界区是指访问某一共享资源的代码片段,并且这段代码的执行应为原子操作,亦即,同时访问同一共享
资源的其他线程不应中断该片段的执行。可以使用互斥量来保证对任意共享资源的原子访问,而保护共享变量是其最常见的用法。
每一线程在访问同一资源时将采用如下协议:
1)针对共享资源锁定互斥量
2)访问共享资源
3)对互斥量解锁
避免死锁,最简单的方法是定义互斥量的层级关系。当多个线程对一组互斥量操作时,总是应该以相同顺序对该组互斥量进行锁定。
互斥量防止多个线程同时访问同一共享变量。条件变量允许一个线程就某个共享变量(或其他共享资源)的状态变化通知其他线程,
并让其他线程等待(阻塞于)这一通知。
导致线程不安全的典型原因:使用了在所有线程之间共享的全局或静态变量。
实现线程安全的方式多样,其一是将函数与互斥量关联使用,在调用函数时将其锁定,在函数返回时解锁。
#include <stdio.h> #include <pthread.h> #include <unistd.h> static int glob=0; static pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER; static void * threadFunc(void *arg) { int loops = *((int *)arg); int loc, j, s; for(j=0; j<loops; j++) { s = pthread_mutex_lock(&mtx); if(s != 0) { fprintf(stderr, "pthread_mutex_lock error."); return (void *)-1; } loc = glob; loc++; glob = loc; s = pthread_mutex_unlock(&mtx); if(s != 0) { fprintf(stderr, "pthread_mutex_unlock error."); return (void *)-1; } } return NULL; } int main() { pthread_t t1, t2; int loops, s; printf("Input the loops: "); scanf("%d", &loops); s = pthread_create(&t1, NULL, threadFunc, &loops); if(s != 0) { fprintf(stderr, "pthread_create error."); return -1; } s = pthread_create(&t2, NULL, threadFunc, &loops); if(s != 0) { fprintf(stderr, "pthread_create error."); return -1; } s = pthread_join(t1, NULL); if(s != 0) { fprintf(stderr, "pthread_join error."); return -1; } s = pthread_join(t2, NULL); if(s != 0) { fprintf(stderr, "pthread_join error."); return -1; } printf("glob = %d\n", glob); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现