线程同步与线程安全

2023-10-26

1线程同步

   同步:多线程访问临界资源时,必须进行同步控制,多进程或者多线程的执行并不完全是绝对的并行运行,又可能主线程需要等待函数线程的某些条件的发生。

  多线程的临界资源有全局数据,堆区数据,文件描述符

 

   同步控制方式:

  1.1信号量

        需要用到头文件semaphore.h

     获取: 

       int sem_init(sem_t *sem,int pshared,ussigned int vale);

                第一个参数是一个sem_t类型指针,指向信号量对象

                第二个参数是多进程间是否线程共享,linux暂不支持,所以为0

                 第三个参数是信号量的初始值

     p操作:

             int sem_wait(sem_t *sem)

     V操作:

          int sem_post(sem_t *sem)

     删除:

     int sem_destroy(sem_t *sem)

举个栗子

主线程获取用户输入,函数线程统计用户输入的字符个数。



   


1.2互斥锁   还有读写锁,自旋锁....

  完全控制临界资源,如果一个线程完成加锁操作,则其他线程无论如何都无法进行加锁,也就无法对临界资源进行访问。相当于最大值为1的信号量,但比信号量的临界控制更加严格。

初始化:int pthread_mutex_init(pthread_mutex_t *mutx,pthread_mutex_attr_t *attr);

       第二个参数pthread_mutex_attr_t *attr为锁的属性,一般为NULL的默认属性。

 

加锁:int pthread_mutex_lock(pthread_mutex_t *mutx); //阻塞运行的版本,即无法加锁就等待

      int pthread_mutex_trylock(pthread_mutex_t *mutx);//非阻塞的版本。能加锁就加锁进入临界区,加不了走人不干等着

解锁:int pthread_mutex_unlock(pthread_mutex_t *mutx);

 

释放(删除):int pthread_mutex_destory(pthread_mutex_t *mutx);

   


2线程安全

  可重入函数:

   某些库函数会使用线程间共享的数据,如果没有同步控制,线程操作是不安全的。

   所以,我们使用这样一些函数时,就必须使用其安全的版本,即可重入函数;

例如 Strtok的 可重入版本 strtok_r

我们知道切割函数一般只用第一次传入字符数组的首地址,之后的切割传入NULL就可以了

为什么可以函数只用传NULL就知道我们上次字符串切割后的首地址,那是由于系统已经有个全局变量储存了。

因此如果两个线程同时使用这个函数去切割不同的字符串,那么全局变量的储存就会出问题。

导致后切割的字符串的切后首地址覆盖了先切割的,最终结果是只切割了第一个字符串一次,然后两个线程共同 去切割另一个字符串了,和我们的预期不符。





因此我们就要用到处理方式更加妥善的可重入函数








线程中fork 

    在线程中,子进程只会启用调用fork函数的那条线程,其他线程不会启用。

需要注意的是

子进程会继承其父进程的锁及锁的状态,但是父子进程用到不是同一把锁,父进程解锁并不会影响到子进程的锁。所以子进程有可能死锁




可以看到子进程的锁卡住了

解决方案为应对这种情况设计的atfork函数,函数如下

 Pthread_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void));

 指定在fork调用之后,创建子进程之前,调用prepare函数,获取所有锁,

然后创建子进程,子进程创建以后,父进程环境中调用parent解所有的锁,子进程环境中调用child解所有的锁,然后fork函数再返回,这样保证了fork之后,子进程拿到的锁都是解锁状态,避免了死锁。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程同步与线程安全 的相关文章

  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • ansible 重新启动 2.1.1.0 失败

    我一直在尝试创建一个非常简单的 Ansible 剧本 它将重新启动服务器并等待它回来 我过去在 Ansible 1 9 上有一个可以运行的 但我最近升级到 2 1 1 0 并且失败了 我正在重新启动的主机名为 idm IP 为 192 16
  • 如何修复“iptables:没有该名称的链/目标/匹配”?

    我在我的 Linux 嵌入式系统上构建并安装了 iptables 如果我列出所有规则 则一切正常 iptables list Chain INPUT policy ACCEPT target prot opt source destinat
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • 使用 find - 删除除任何一个之外的所有文件/目录(在 Linux 中)

    如果我们想删除我们使用的所有文件和目录 rm rf 但是 如果我希望一次性删除除一个特定文件之外的所有文件和目录怎么办 有什么命令可以做到这一点吗 rm rf 可以轻松地一次性删除 甚至可以删除我最喜欢的文件 目录 提前致谢 find ht
  • bluetoothctl 到 hcitool 等效命令

    在 Linux 中 我曾经使用 hidd connect mmac 来连接 BT 设备 但自 Bluez5 以来 这种情况已经消失了 我可以使用 bluetoothctl 手动建立连接 但我需要从我的应用程序使用这些命令 并且使用 blue
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 无法加载 JavaHL 库。- linux/eclipse

    在尝试安装 Subversion 插件时 当 Eclipse 启动时出现此错误 Failed to load JavaHL Library These are the errors that were encountered no libs
  • 如何通过替换为空页映射来取消映射 mmap 文件

    Linux 用户空间有没有办法用空页面 映射自 dev null 或者可能是一个空页面 重复映射到从文件映射的页面的顶部 对于上下文 我想找到这个 JDK bug 的修复 https bugs openjdk java net browse
  • 仅打印“docker-container ls -la”输出中的“Names”列

    发出时docker container ls la命令 输出如下所示 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a67f0c2b1769 busybox tail f dev
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • Linux中的定时器类

    我需要一个计时器来以相对较低的分辨率执行回调 在 Linux 中实现此类 C 计时器类的最佳方法是什么 有我可以使用的库吗 如果您在框架 Glib Qt Wx 内编写 那么您已经拥有一个具有定时回调功能的事件循环 我认为情况并非如此 如果您
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • 尝试安装 LESS 时出现“请尝试以 root/管理员身份再次运行此命令”错误

    我正在尝试在我的计算机上安装 LESS 并且已经安装了节点 但是 当我输入 node install g less 时 出现以下错误 并且不知道该怎么办 FPaulMAC bin paul npm install g less npm ER
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at

随机推荐

  • 统计学——卡方检验和卡方分布

    什么是卡方检验 卡方检验是一种用途很广的计数资料的假设检验方法 它属于非参数检验的范畴 主要是比较两个及两个以上样本率 构成比 以及两个分类变量的关联性分析 其根本思想就是在于比较理论频数和实际频数的吻合程度或拟合优度问题 它在分类资料统计
  • 目标检测标注原则

    算力和数据是影响深度学习应用效果的两个关键因素 在算力满足条件的情况下 为了到达更好的效果 我们需要将海量 高质量的素材数据喂给神经网络 训练出高精度的网络模型 吴恩达在深度学习公开课中提到 在算力满足要求的前提下 模型效果会随着素材数量的
  • vue事件绑定、事件参数、事件修饰符、表单双向绑定、监听器、计算属性

    目录 事件绑定 事件参数 事件修饰符 表单 watch 监听器 监听属性 computed 计算属性 面试题 事件机制 概述 在dom阶段 我们已经讲述了事件机制的特点 事件三要素 事件绑定 事件流 事件对象 事件代理 事件类型 这些概念在
  • ISAKMP - 安全关联协商

    前面说过 ISAKMP主要有三个过程 SA协商 密钥交换和认证 本篇主要讨论SA协商 首先要明白一个问题 为什么需要协商 为什么协议不规定使用某种特定的算法 这样实现上可以变得简单很多 要回答这个问题 我们必须全面的审视网络通信的环境 所有
  • Redis中常用命令:基本+五种基本类型(string、list、hash、set、zset)+三种特殊类型(geospatial、hyperloglog、bitmap)

    redis的命令有很多 命令不区分大小写 如下是一些常用的命令 可以通过官网 命令来学习使用更多的命令 例如 1 基本命令 选择数据库select 编号 redis默认的数据库有16个 编号从0 15 默认使用0号数据库 在配置文件中可查看
  • Elasticsearch(三)使用 Kibana 操作 ES

    文章目录 下载 Kibana 镜像 启动 Kibana 容器 索引 分片和副本 索引 索引分片 索引副本 创建索引 映射 数据结构 字段的数据类型 创建映射 查看映射 添加文档 删除文档 删除索引 下载 Kibana 镜像 docker p
  • Deep Java Library(DJL)上手指南

    Deep Java Library DJL https djl ai 是一个Java语言编写的深度学习库 平台 支持各种已有的模型直接导入 受益于Java的跨平台和高性能 相对Python DJL可以很容易部署和高效率运行 尤其是推理 首先
  • uc3842改可调电源教程_《学习笔记》--DC/DC电源电路设计实例

    1 设计概述 利用LTC3704实现3 3V 1 5V的转换 最大输出电流1A LTC3704是一款支持正向电源电压转换为负向电源电压的DC DC电源芯片 支持的输入端电源电压范围是2 5V 36V 输出端电源电压可调 2 引脚介绍 VIN
  • 若依前端后端框架 分离切换用户问题解决!学不会得找我!!!

    笔者最近遇到一个问题 就是有主账号一个字段 有多个从账号 基于这个目的用户表登录名是从账号得登录名 而有一个字段为主账号 识别是这个人 若依前后端 看了官网 都是用userName去鉴权 然后生成token和JWT数据 所有userName
  • todolist 案例 JavaScript

    css样式 body margin 0 padding 0 font size 16px background CDCDCD header height 50px background 333 background rgba 47 47 4
  • VUE 巧用$attrs和inheritAttrs提高组件的可扩展性

    VUE 巧用 attrs和inheritAttrs提高组件的可扩展性 前言 在平时创建组件时 一般使用的是利用props传值 然后通过传入的值再赋给标签的方式 来控制组件里的 这种方法在使用时的可扩展性不大 很难通过外部来动态的往组件内部添
  • java学习笔记(第7天:形参和返回值)

    目录 一 形参和返回值都是基本类型 二 类名作为形参和返回值 三 抽象类作为形参和返回值 四 接口作为形参和返回值 一 形参和返回值都是基本类型 这里比较简单 放一个不确定参数数量的例子玩玩 package Demo public clas
  • 关于Unity游戏开发场景切换:Time.timeScale的捣乱

    在制作场景切换功能的时候 我用的是SceneManager LoadScene函数 从主界面场景切换到关卡1场景 从关卡1场景切换到关卡2场景都是没有问题的 但是 当我在点击Pause按钮来到暂停界面 点击Back Menu按钮准备回到主界
  • LR和线性回归的区别与联系

    区别 区别 线性回归 liner regression LR logistics regression 构建方法 最小二乘法 似然函数 解决问题 主要解决回归问题 也可以用来分类 但是鲁棒性差 解决分类问题 输出 输出实数域上连续值 输出值
  • 在#define中使用参数

    在 define中使用参数 在 define中使用参数可以创建外形和作用与函数类似的类函数宏 例如 define SQUARE X X X 在程序中可以这样用 z SQUARE 2 这看上去像函数调用 但它的行为与函数调用完全不同 预处理器
  • 网关Gateway-快速上手

    gateway网关官方文档 https docs spring io spring cloud gateway docs current reference html 网关的概念 网关作为流量的入口 常用的功能包括路由转发 权限校验 限流等
  • 单片机:按键(使用中断)控制数码管的数字加减(c语言实现)

    本实验的目的 使用中断实现通过编号为8和C的按键控制数码管数字的加减 加至15之后再循环到0 减到0之后保持0不变 include
  • Python Django项目URL中包含另外一个urls模块

    在我们的项目中 不可能只有一个app 如果把所有的app的views中的视图都放在urls py中进行映射 肯定会让代码显得非常乱 因此django给我们提供了一个方法 可以在app内部包含自己的url匹配规则 而在项目的urls py中再
  • win11 设置系统环境变量

    由于win11的设置面板大变样 一时之间找不到高级设置进入系统环境变量的设置 面对这个问题可以这样 1 按win键 在搜索中输入 编辑系统环境变量 如图
  • 线程同步与线程安全

    1线程同步 同步 多线程访问临界资源时 必须进行同步控制 多进程或者多线程的执行并不完全是绝对的并行运行 又可能主线程需要等待函数线程的某些条件的发生 多线程的临界资源有全局数据 堆区数据 文件描述符 同步控制方式 1 1信号量 需要用到头