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

linux17 线程安全 线程同步

1、线程安全:

多线程程序无论调度顺序如何,都能保证程序 的正确性,就说该程序处于线程安全的状态

1)、同步

2)、线程安全函数//有的函数不适合多线程使用,是函数自身的原因。

2、线程安全函数

1)非线程安全函数

分割函数//不是线程安全函数

strtok(buff,"  分隔符")//非线程安全函数,

如果有静态变量或者全局变量,对于多线程来说,访问是不安全的。属于非线程安全函数

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>void *fun(void*arg)
{
char buff[128]={a b c d };
char*s=strtok(buff," ");
while(s!=NULL)
{
printf("%s\n",s);
s=strtok(NULL," ");
}}int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
char arr[128]={1 2 3 4 5};
char*p=strtok(arr," ");
whlie(p!=NULL)
{
printf("%s\n",p);
p=strtok(NULL," ");
}
pthread_join(id,NULL);
exit(0);
}

2)线程安全函数 

线程安全分割函数

strtok_r(buff," ",&ptr);

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>void *fun(void*arg)
{
char buff[128]={a b c d };
char*ptr=NULL;
char*s=strtok_r(buff," ",&ptr);
while(s!=NULL)
{
printf("%s\n",s);
s=strtok_r(NULL," ",&ptr);
}}int main()
{
pthread_t id;
pthread_create(&id,NULL,fun,NULL);
char arr[128]={1 2 3 4 5};
char*ptr=NULL;
char*p=strtok_r(arr," ",&ptr);
whlie(p!=NULL)
{
printf("%s\n",p);
p=strtok_r(NULL," ",&ptr);
}
pthread_join(id,NULL);
exit(0);
}

3、多线程程序执行fork()

1)多线程程序:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>void*fun(void *arg)
{
for(int i=0;i<5;i++)
{
printf("fun(%d) run\n",getpid());
sleep(1);
}}int main()
{pthread_t id;
pthread_create(&id,NULL,fun,NULL);for(int i=0;i<5;i++)
{
printf("main(%d) run\n",getpid());
sleep(1);
}pthread_join(id,NULL);
exit(0);
}

2)多线程 复制子进程

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>void*fun(void *arg)
{
for(int i=0;i<5;i++)
{
printf("fun(%d) run\n",getpid());
sleep(1);
}}int main()
{pthread_t id;
pthread_create(&id,NULL,fun,NULL);fork ();for(int i=0;i<5;i++)
{
printf("main(%d) run\n",getpid());
sleep(1);
}pthread_join(id,NULL);
exit(0);
}

多线程 fork()后只会执行一条路径,他在哪一个路径中他就会执行那一条路径,但是其他路径的资源他是有的,只不过不执行了

4、创建一个锁,fork()之后看子进程的情况

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/wait.h>pthread_mutex_t mutex;
void*fun(void *arg)
{pthread_mutex_lock(&mutex);
sleep(5);//线程睡眠5秒
pthread_mutex_unlock(&mutex);
printf(" fun free\n");
}int main()
{pthread_t id;
pthread_mutex_init(&mutex,NULL);
pthread_create(&id,NULL,fun,NULL);sleep(1);//主线程睡眠一秒pid_t pid=fork();//复制的时候,父进程处于加锁状态
if(pid==0)
{
printf("child lock\n");
pthread_mutex_lock(&mutex);
printf("child success");
pthread_mutex_unlock(&mutex);
}
else
{
wait(NULL);
}printf("main over");pthread_mutex_destroy(&mutex);
pthread_join(id,NULL);
exit(0);}

子进程没有加锁成功 

1)加锁失败原因:

 父进程和子进程的锁各自是各自的,是两把锁。

锁的状态,会在复制进程时,被复制,在复制时,父进程的锁是加锁,复制后,子进程的锁也是加锁,同样不加锁也是。是不固定的,子进程中锁的状态不清晰。

2)解决办法:pthread_atfork()

会在没有人用锁的情况下对进程进行复制,确保子进程所得状态时清晰的。

void parent_fun(void)
{
pthread_mutex_lock(&mutex);
}
void child_fun(void)
{
pthread_mutex_unlock(&mutex);
}int main()
{
pthread_atfork(parent_fun,child_fun.child_fun);
//写入主函数,会在复制子程序之前执行
}

弊端是会延迟fork的复制

5、进程同步——条件变量

进程同步的方法:信号量  互斥锁   读写锁   条件变量

线程先将自己堵塞在条件变量等待队列上,等条件满足之后,唤醒一个或者全部

//条件满足就工作,条件不满足就休息//条件由用户决定。

在唤醒的时候,不希望有别的进出这个给队列,所以在唤醒时加锁

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>pthread_mutex_t mutex;
pthread_cond_t cond;char buff[128]={0};void *funa(void*arg)
{
while(1)
{pthread_mutex_lock(&mutex);//唤醒前加锁pthread_cond_wait(&cond,&mutex);pthread_mutex_unlock(&mutex);if(strncmp(buff,"end",3)==0){printf("funa:%s",buff);}}}
void*funb(void*arg)
{
{while (1){pthread_mutex_lock(&mutex);pthread_cond_wait(&cond,&mutex);pthread_mutex_unlock(&mutex);}if(strncmp(buff,"end",3)==0){printf("funb:%s",buff);}}
}int main()
{pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
pthread_t id1,id2;
pthread_create(&id1,NULL,funa,NULL);
pthread_create(&id2,NULL,funb,NULL);while(1)
{char tmp[128]={0};fgets(tmp,128,stdin);strcpy(buff,tmp);if(strncmp(tmp,"end",3)==0){pthread_cond_broadcast(&cond);//唤醒全部进程break;}else{pthread_cond_signal(&cond);//唤醒单个进程(轮流唤醒)}
}pthread_join(id1,NULL);
pthread_join(id2,NULL);
}

相关文章:

linux17 线程安全 线程同步

1、线程安全&#xff1a; 多线程程序无论调度顺序如何&#xff0c;都能保证程序 的正确性&#xff0c;就说该程序处于线程安全的状态 1&#xff09;、同步 2&#xff09;、线程安全函数//有的函数不适合多线程使用&#xff0c;是函数自身的原因。 2、线程安全函数 1&#…...

lvs集群与nat模式

一&#xff0c;什么是集群&#xff1a; 集群&#xff0c;群集&#xff0c;Cluster&#xff0c;由多台主机构成&#xff0c;但是对外只表现为一个整体&#xff0c;只提供一个访问入口&#xff08;域名与ip地址&#xff09;&#xff0c;相当于一台大型计算机。 二&#xff0c;集…...

【开源分享】在线客服系统搭建-基于php和swoole客服系统CRMchat(附源码完整搭建教程)...

CRMChat是一款开源的在线客服系统&#xff0c;后台管理使用thinkphp框架&#xff0c;消息通讯使用swoole扩展&#xff0c;现在我来部署搭建一下。 这是一款不可商用的开源客服系统&#xff0c;如果有商用需求可以访问我的网站&#xff1a;gofly.v1kf.com 域名解析 以阿里云为例…...

Webpact学习笔记记录

Webpact学习笔记记录 一.初始化项目1.生成package.json2.安装webpack3.执行webpack体验 二、webpack的配置文件三、less-loader解析less1.安装loader2.配置 四、eslint-loader语法检查1.安装loader2.配置loader3.在package.json中加入 五、js语法转换1.安装loader2.配置loader …...

Python代码实现解析MULTIPOLYGON几何对象类型数据为嵌套列表

MULTIPOLYGON MULTIPOLYGON是一种地理信息系统&#xff08;GIS&#xff09;中的几何对象类型&#xff0c;用于表示由多个多边形组成的复杂地理区域。它是一种多边形的集合&#xff0c;每个多边形可以是简单的凸多边形或复杂的凹多边形。 MULTIPOLYGON类型的几何对象通常用于描…...

SSH连接工具汇总

xshell 这是个熟悉的软件啦&#xff0c;目前我正在使用Xshell_7 链接&#xff1a;https://www.xshell.com/zh/xshell/ FinalShell 国产软件&#xff0c;有windows和MAC版本&#xff1b;使用方便而且免费&#xff0c;但是软件比较占用内存。但是都2021年了&#xff0c;笔记本…...

Java的AQS框架是如何支撑起整个并发库的

如何设计一个抽象队列同步器 引言AQS需要解决哪些场景下的问题互斥模式获取锁抢锁失败入队 释放锁小总结 共享模式获取共享资源释放共享资源唤醒丢失问题 小总结 混合模式获取写锁释放写锁获取读锁读锁是否应该阻塞 释放读锁小总结 栅栏模式等待递减计数 条件变量模式等待条件成…...

一.net core 自动化发布到docker (Jenkins安装)

目录 1.安装Jenkins 参考资料:https://www.jenkins.io/doc/book/installing/docker/#downloading-and-running-jenkins-in-docker 1.Open up a terminal window.(打开一个终端窗口。) 2.Create a bridge network in Docker using the following docker network create comma…...

二刷LeetCode--148. 排序链表(C++版本),必会题,思维题

思路&#xff0c;本题其实考察了两个点&#xff1a;合并链表、链表切分。首先从1开始&#xff0c;将链表切成一段一段&#xff0c;因为需要使用归并&#xff0c;所以下一次的切分长度应该是当前切分长度的二倍&#xff0c;每次切分&#xff0c;我们拿出两段&#xff0c;然后将第…...

css flex 上下结构布局

display: flex; flex-flow: column; justify-content: space-between;...

win下qwidget全屏弹窗后其他窗口鼠标样式无法更新的问题

在win平台下&#xff0c;实现截取选桌面执行推理功能&#xff0c;用一个qwidget(j对象名为m_selectWidget)来显示选取范围的边框&#xff0c;但这个qwidget显示后&#xff0c;其他窗口在他下面可以接受鼠标相应的事件&#xff0c;但原来的鼠标形状功能失效&#xff08;mac正常&…...

Java【数据结构】二分查找

&#x1f31e; 题目&#xff1a; &#x1f30f;在有序数组A中&#xff0c;查找目标值target &#x1f30f;如果找到返回索引 &#x1f30f;如果找不到返回-1 算法描述解释前提给定一个内含n个元素的有序数组A&#xff0c;满足A0<A1<A2<<An-1,一个待查值target1设…...

数据库技术--数据库引擎,数据访问接口及其关系详解(附加形象的比喻)

目录 背景数据库引擎Jet数据库&#xff1a;ISAM&#xff1a;ODBC&#xff08;Open Database Connectivity&#xff09;&#xff1a; 数据访问接口ADO&#xff08;ActiveX Data Objects&#xff09;DAO&#xff08;Data Access Objects&#xff09;RDO&#xff08;Remote Data O…...

【BASH】回顾与知识点梳理(三十三)

【BASH】回顾与知识点梳理 三十三 三十三. 认识系统服务 (daemons)33.1 什么是 daemon 与服务 (service)早期 System V 的 init 管理行为中 daemon 的主要分类 (Optional)systemd 使用的 unit 分类systemd 的配置文件放置目录systemd 的 unit 类型分类说明 33.2 透过 systemctl…...

同步请求和异步请求

同步请求和异步请求是在网络编程中常用的两种通信模式&#xff0c;它们有以下区别&#xff1a; 同步请求&#xff1a; 在发送一个请求后&#xff0c;程序会一直等待服务器返回响应&#xff0c;期间无法进行其他操作。请求发出后&#xff0c;程序会阻塞在请求处&#xff0c;直…...

Transformer是什么,Transformer应用

目录 Transformer应用 Transformer是什么 Transformer应用:循环神经网络 语言翻译:注重语句前后顺序 RNN看中单个特征; CNN:看中特征之间时序性 模型关注不同位置的能力 Transformer是什么 Transformer是一个利用注意力机制来提高模型训练速度的模型。关于注意力机…...

故障011:dmap服务缺失libnsl.so修复

故障011&#xff1a;dmap服务缺失libnsl.so修复 1. 问题描述2. 解决方法2.1 初步分析2.2 动手实操2.2.1 模糊搜索大法2.2.2 僵桃代李大法 DM技术交流QQ群&#xff1a;940124259 1. 问题描述 今天遇二期XC环境&#xff0c;达梦DM 7.6的DmAPService备份辅助进程服务无法启动&a…...

第十三章 SpringBoot项目(总)

1.创建SpringBoot项目 1.1.设置编码 1.4.导入已有的spring boot项目 2.快速搭建Restfull风格的项目 2.1.返回字符串 RestController public class IndexController {RequestMapping("/demo1")public Object demo1() {System.out.println("demo1 ran...."…...

利用Python隧道爬虫ip轻松构建全局爬虫网络

嘿&#xff0c;爬虫程序员们&#xff01;你们有没有碰到过需要大规模数据爬取的情况&#xff1f;也许你们之前遇到过网站的反爬措施&#xff0c;卡住你们的进度。别担心&#xff0c;今天我来分享一个利用Python隧道爬虫ip实现的方法&#xff0c;帮助你们轻松搭建全局爬虫ip网络…...

Spring Clould 网关 - Gateway

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; Gateway网关-网关作用介绍&#xff08;P35&#xff09; Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2…...

【DeepSeek开源协议识别权威指南】:20年合规专家亲授3大协议陷阱与5步精准识别法

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek开源协议识别的底层逻辑与合规价值 DeepSeek系列模型&#xff08;如DeepSeek-V2、DeepSeek-Coder&#xff09;虽以“开源”名义发布&#xff0c;但其实际许可状态需通过结构化协议解析才能准确…...

AI圈内火热的Agent、MCP、Skill、CLI是啥?用装修房子讲透,看完秒懂

本文用装修房子的比喻&#xff0c;详细解释了AI领域的四个核心概念&#xff1a;Agent如同会自主规划任务的私人助理&#xff1b;MCP是AI与外部工具数据的统一接口&#xff0c;类似USB-C&#xff1b;Skill是指导AI按标准操作执行的手册&#xff1b;CLI则是不依赖图形界面的命令行…...

【数据结构与算法】数据结构基础——栈和队列

目录栈和队列1. 栈1.1 栈的概念1.2 栈的实现方式分析1.3 栈的实现1.3.1 栈的初始化与销毁1.3.2 入栈与出栈1.3.3 栈的判空与有效元素个数1.3.4 栈顶元素1.4 栈的扩展1.4.1 两栈共享空间2. 队列2.1 队列的概念2.2 队列的实现方式分析2.3 队列的实现2.3.1 队列的初始化与销毁2.3.…...

鸿蒙HarmonyOS 5与Unity跨运行时通信实战指南

1. 这不是“调个API”那么简单&#xff1a;为什么鸿蒙Unity通信总在临门一脚卡住我第一次把Unity打包的AR模块塞进HarmonyOS 5 App里时&#xff0c;信心满满——毕竟文档里写着“支持JS/ArkTS调用Native能力”&#xff0c;Unity也标榜“跨平台通用”。结果呢&#xff1f;App一启…...

OpenCore Legacy Patcher完整指南:让老旧Mac焕发新生,运行最新macOS

OpenCore Legacy Patcher完整指南&#xff1a;让老旧Mac焕发新生&#xff0c;运行最新macOS 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否有一台被苹…...

告别Selenium?手把手教你用Playwright录制脚本,5分钟搞定Web自动化测试

5分钟极速上手Playwright脚本录制&#xff1a;零代码实现Web自动化测试当产品经理突然丢给你一个刚上线的电商活动页&#xff0c;要求半小时内完成所有核心链路测试时&#xff0c;传统的手写Selenium脚本显然来不及。作为测试工程师&#xff0c;我最近发现微软开源的Playwright…...

安卓用户如何免费获取大模型API密钥并开始调用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 安卓用户如何免费获取大模型API密钥并开始调用 对于安卓开发者或移动端技术爱好者而言&#xff0c;直接体验和调用多种大模型的能力…...

密码学入门:区块链中的密码学原理

密码学入门&#xff1a;区块链中的密码学原理 大家好&#xff0c;我是欧阳瑞&#xff08;Rich Own&#xff09;。今天想和大家聊聊密码学这个重要话题。作为一个Web3探索者&#xff0c;密码学是区块链的基础。今天就来分享一下区块链中常用的密码学原理。 为什么密码学很重要&a…...

基于Shapley值与随机森林的印度CPI通胀预测与特征重要性分析

1. 项目概述与核心价值在宏观经济预测领域&#xff0c;通胀预测的准确性直接关系到货币政策制定、市场预期管理乃至社会民生稳定。传统的计量经济学模型&#xff0c;如基于菲利普斯曲线的线性回归&#xff0c;虽然具有良好的可解释性&#xff0c;但在捕捉现实世界中复杂、非线性…...

Linux命令:perf

perf 命令 基本介绍 perf&#xff08;Performance Counters for Linux&#xff09;是 Linux 系统中用于性能分析的强大工具套件。它基于内核性能计数器&#xff08;PMC&#xff09;&#xff0c;可以分析 CPU 使用率、内存访问、缓存命中率、分支预测等硬件级性能指标&#xff0…...