【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-12-18git仓库有更新,jenkins 自动触发拉代码怎么配置的?-icode9专业技术文章分享
- 2024-12-18Jenkins webhook 方式怎么配置指定的分支?-icode9专业技术文章分享
- 2024-12-13Linux C++项目实战入门教程
- 2024-12-13Linux C++编程项目实战入门教程
- 2024-12-11Linux部署Scrapy教程:新手入门指南
- 2024-12-11怎么将在本地创建的 Maven 仓库迁移到 Linux 服务器上?-icode9专业技术文章分享
- 2024-12-10Linux常用命令
- 2024-12-06谁看谁服! Linux 创始人对于进程和线程的理解是…
- 2024-12-04操作系统教程:新手入门及初级技巧详解
- 2024-12-04操作系统入门:新手必学指南