【Linux】线程安全——线程同步(信号量)
2021/11/28 7:13:03
本文主要是介绍【Linux】线程安全——线程同步(信号量),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- (一)问题描述
- (1)未同步(异步)多线程代码
- (二)信号量控制线程同步
- (1)同步多线程代码
我们简单写个多个线程并发对一个全局变量进行++操作
(一)问题描述
创建5个线程,一个全局变量gdata = 0; 让每个线程都对gdata进行++100次,理想结果就是499
(1)未同步(异步)多线程代码
- 代码
#include <stdio.h> #include <string.h> #include <pthread.h> int gdata = 0; void* pthread_fun(void* arg) { for(int i = 0; i < 100; i++) { printf("gdata_after = %d\n", gdata++); } } int main() { pthread_t id[5]; //创建5个线程 for(int i = 0; i < 5; i++) { pthread_create(&id[i], NULL, pthread_fun, NULL); } //等待五个进程结束 for(int i = 0; i < 5; i++) { pthread_join(id[i], NULL); } return 0; }
- 结果:可以看到gdata时而499,时而498,很明显程序有问题!!
(二)信号量控制线程同步
思路:使用一个信号量加以控制,即可,因为不在乎是那个线程先运行,所以只要保证再gdata++的时候,让其他的线程阻塞就好了,这样就能保证最后的结果== 499
(1)同步多线程代码
代码:
- sem.h
#include <stdio.h> #include <unistd.h> #include <sys/sem.h> union semun { int val; }; void sem_init(); void sem_p(); void sem_v(); void sem_destory();
- sem.c
#include "sem.h" //信号量集的id static int semid = -1; void sem_init() { //创建 semid = semget((key_t)8888, 1, IPC_CREAT | IPC_EXCL | 0600); if(semid == -1) { semid = semget((key_t)8888, 0, IPC_CREAT); if(semid == -1) { perror("semget err"); return; } } //初始化 else { //定义1个信号量 union semun sem_val; sem_val.val = 1; if(semctl(semid, 0, SETVAL, sem_val) == -1) { perror("sem_val init err"); return; } } } void sem_p() { struct sembuf buf; buf.sem_num = 0; buf.sem_op = -1; buf.sem_flg = SEM_UNDO; if(semop(semid, &buf, 1) == -1) { printf("sem_p err\n"); return; } } void sem_v(int index) { struct sembuf buf; buf.sem_num = 0; buf.sem_op = 1; buf.sem_flg = SEM_UNDO; if(semop(semid, &buf, 1) == -1) { printf("sem_v err\n"); return; } } void sem_destory() { if(semctl(semid, 0, IPC_RMID) == -1) { perror("sem_destory err"); return; } }
- new.c
#include "sem.h" #include <pthread.h> #include <unistd.h> int gdata = 0; void* pthread_fun(void* arg) { int* index = (int*)arg; sem_p(*index); for(int i = 0; i < 100; i++) { printf("gdata_after = %d\n", gdata++); } sem_v(*index); } int main() { //初始化信号量集 sem_init(); pthread_t id[5]; //创建5个线程 for(int i = 0; i < 5; i++) { pthread_create(&id[i], NULL, pthread_fun, &i); } //等待五个进程结束 for(int i = 0; i < 5; i++) { pthread_join(id[i], NULL); } //销毁信号量集 sem_destory(); return 0; }
- 结果:在多次实验下,使用信号量保证了线程安全
这篇关于【Linux】线程安全——线程同步(信号量)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法