当前位置: 首页 > 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…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...