Linux C中多线程与volatile变量

Linux C中多线程与volatile变量

volatile 修饰的变量表示改变量的值是易变的,编译器不对其进行优化,访问该变量的时候不会从寄存器读取, 而是直接从内存读取变量。

在多线程环境下,每个线程都有一个独立的寄存器,用于保存当前执行的指令。假设我们定义了一个全局变量,每个线程都会访问这个全局变量,这时候线程的寄存器可能会存储全量变量的当前值用于后续的访问。当某个线程修改了全局变量的值时,系统会立即更新该线程寄存器中对应的值,其他线程并不知道这个全局变量已经修改,可能还是从寄存器中获取这个变量的值,这个时候就会存在不一致的情况。

针对多线程访问共享变量而且变量还会经常变化的情况,利用volatile类型修饰变量是一个很好的选择,如volatile int size = 10; 当多线程访问这个变量时,它会直接从size对应的地址访问,而不会从线程对应的寄存器访问,这样就不会出现前面说到的
同一变量的值在多个线程之间不一致的情况。

下面贴出一个多线程环境下使用 volatile 变量的例子:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> 

/* volatile变量控制线程的运行与结束 */
static volatile int do_run_thread = 1;  

static pthread_t thread_tid; 

static void *work_thread(void *arg)
{
  while (do_run_thread) {
    printf("thread is running...\n");
    sleep(1);
  }
  printf("stop thread done!\n");
} 

static void start_thread()
{
  printf("start thread...\n");
  pthread_create(&thread_tid, NULL, work_thread, NULL);
} 

static void stop_thread()
{
  printf("stop thread...\n");
  do_run_thread = 0;
  pthread_join(thread_tid, NULL); /* 等待线程结束 */
} 

int main()
{
  start_thread();
  sleep(5);
  stop_thread(); 

  return 0;
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Linux C中sockaddr和sockaddr_in的区别

    Linux C中sockaddr和sockaddr_in的区别 struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址. 在各种系统调用或者函数中,只要和网络地址打交道,就得用到这两个结构体. 网络中的地址包含3个方面的属性: 1 地址类型: ipv4还是ipv6 2 ip地址 3 端口 相应的,头文件有如下定义: include <netinet/in.h> struct sockaddr { unsigned short sa_family;

  • Linux系统中利用node.js提取Word(doc/docx)及PDF文本的内容

    前言 想要做全文搜索引擎,则需要将word/pdf等文档内容提取出来.对于pdf有xpdf等一些开源方案. 但Word文档的情况则会复杂一些. 提取PDF文本内容 XPDF是一个免费开源的软件,用于显示PDF文件,并可将pdf转换成文字图片等,同样支持Windows版.在Debian Linux上安装非常简单: apt-get install xpdf 我们这里只使用pdftotext这个功能,直接输入可查看帮助: root@raspberrypi:/var/www# pdftotext pdf

  • linux下tomcat常用操作

    假设tomcat安装在/usr/local/tomcat7 启动tomcat cd /usr/local/tomcat7/bin ./startup.sh 查看启动状态 ps -ef|grep java root 3729 1729 6 09:23 pts/2 00:00:03 /usr/lib/jvm/java-8-openjdk-i386//bin/java -Djava.util.logging.config.file=/usr/local/tomcat7/conf/logging.pro

  • Oracle Linux 6.8安装 mysql 5.7.17的详细教程

    安装MySQL 5.7.17的方法如下所示: 1.下载 http://www.codeyyy.com/linux/149-150-153.html 2.上传解压 tar -xvf mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz 3.新建mysql目录 mkdir -p /usr/local/mysql/data mv mysql-5.7.17-linux-glibc2.5-x86_64/* /usr/local/mysql/ 4.添加用户组 groupadd

  • 详谈Linux写时拷贝技术(copy-on-write)必看篇

    COW技术初窥 在linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了"写时复制"技术,也就是只有进程空间的各段的内容要发生变化时,才将父进程的内容复制一份给子进程. 那么子进程的物理空间没有代码,怎么去取指令执行exec系统调用呢?? 在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段.数据段.堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,其对应的物理空间是一

  • NetCore1.1+Linux部署初体验

    NetCore1.1+Linux部署初体验 1.环境准备 Centaos7+Win10 虚拟机 Win10安装VS2017 注意勾选下.Net Core 3.Centaos安装netcore 1.1参见https://www.microsoft.com/net/core sudo yum install libunwind libicu curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821 sudo m

  • Linux编程之ICMP洪水攻击

    我的上一篇文章<Linux编程之PING的实现>里使用ICMP协议实现了PING的程序,ICMP除了实现这么一个PING程序,还有哪些不为人知或者好玩的用途?这里我将介绍ICMP另一个很有名的黑科技:ICMP洪水攻击. ICMP洪水攻击属于大名鼎鼎的DOS(Denial of Service)攻击的一种,一种是黑客们喜欢的攻击手段,这里本着加深自己对ICMP的理解的目的,也试着基于ICMP写一段ICMP的洪水攻击小程序. 洪水攻击(FLOOD ATTACK)指的是利用计算机网络技术向目的主机发

  • 详解Linux系统中网卡MAC地址克隆方法

    怎么临时性地改变 MAC 地址? 你可以在 Linux 运行的时候改变 MAC 地址.需要注意的是当 MAC 地址转换的那一会时间,你的网络会掉线.当电脑重启时 MAC 地址又会变回原来的.下面介绍几种方法来改变你的 MAC 地址. 方法一:iproute2 $sudo ip link set dev eth0 down $sudo ip link set dev eth0 address 00:00:00:00:00:01 $sudo ip link set dev eth0 up 方法二:m

  • Linux C中多线程与volatile变量

    Linux C中多线程与volatile变量 volatile 修饰的变量表示改变量的值是易变的,编译器不对其进行优化,访问该变量的时候不会从寄存器读取, 而是直接从内存读取变量. 在多线程环境下,每个线程都有一个独立的寄存器,用于保存当前执行的指令.假设我们定义了一个全局变量,每个线程都会访问这个全局变量,这时候线程的寄存器可能会存储全量变量的当前值用于后续的访问.当某个线程修改了全局变量的值时,系统会立即更新该线程寄存器中对应的值,其他线程并不知道这个全局变量已经修改,可能还是从寄存器中获取

  • 深入探讨Java多线程中的volatile变量

    volatile 变量提供了线程的可见性,并不能保证线程安全性和原子性. 什么是线程的可见性: 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility).互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据.可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 -- 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前

  • Linux中多线程详解及简单实例

    Linux中多线程详解及简单实例 1.概念 进程:运行中的程序. 线程:一个程序中的多个执行路径.更准确的定义是:线程是一个进程内部的一个控制序列. 2.为什么要有线程? 用fork调用进程代价太高,需要让一个进程同时做多件事情,线程就非常有用. 3.线程的优点和缺点. 优点: (1)有时,让程序看起来是在同时做两件事是非常有用的. 比如在编辑文档时,还能统计文档里的单词个数. (2)一个混杂着输入.计算.输出的程序,利用线程可以将这3个部 分分成3个线程来执行,从而改变程序执行的性能. (3)

  • 在Linux操作系统中修改环境变量的方法

    方法一:在/etc/profile文件中添加变量[对所有用户生效(永久的)] 用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是"永久的". 要让刚才的修改马上生效,需要执行以下代码 复制代码 代码如下: # source /etc/profile 方法二:在用户目录下的.bash_profile文件中增加变量[对单一用户生效(永久的)] 用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是&quo

  • linux 下python多线程递归复制文件夹及文件夹中的文件

    本文是利用python 复制文件夹 刚开始写了一个普通的递归复制文件夹    然后想了想 觉得对io频繁的程序 threading 线程还比较友好  就写了个多线程版本的  最恶心人的地方就是路径  其他都还好吧 import os import threading import multiprocessing length_of_folder = 0 def copyfile(Path): if os.path.isdir(Path): print("-----------%s" %

  • Linux下的多线程编程实例解析

    1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程.现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux. 为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比,它

  • C++中多线程的执行顺序如你预期吗

    目录 一个简单的例子 诡异的输出结果 你看到的执行顺序不是真的执行顺序 你看到的执行顺序还不是真正的执行顺序 C++多线程内存模型 一个简单的例子 先来看一个多线程的例子: 如图所示,我们将变量x和y初始化为0,然后在线程1中执行: x = 1, m = y; 同时在线程2中执行: y = 1, n = x; 当两个线程都执行结束以后,m和n的值分别是多少呢? 对于已经工作了n年.写过无数次并发程序的的我们来说,这还不是小case吗?让我们来分析一下,大概有三种情况: 如果程序先执行了x = 1

  • Java中的关键字volatile详解

    volatile关键字经常用来修饰变量.不过,volatile本身很容易被误用.本篇就介绍一下volatile的原理和使用方式. 在介绍volatile关键字原理前,我们首先要了解JVM运行时的内存分配逻辑. 对于成员变量i,它存储在堆内存中.每个线程在运行时都会有一个自己的线程栈,线程如果要访问类的成员变量i,会通过引用获取到堆中变量i实际的值10,然后把这个变量值拷贝到自己的栈内存中,作为一个变量副本,之后线程便不再会与堆中的变量有实际联系.每个线程都有一个自己的本地副本,相互隔离.线程访问

  • C++中const、volatile、mutable使用方法小结

    相信const大家对他并不陌生,可能大家在日常的编写代码当中就会时常用到const,但是剩下的两个关键字不知道我们有 没有使用过volatile和mutable两个关键字其实不算特别常用,但是我们一定要知道这个关键字有什么用,应该怎么用.首 先const的基本操作我曾经写过一篇博客:const的基本使用 现在我要说一个const操作里面比较骚的一些做法, 举个例子我们以前写过的一个类,我们会使用operator[]来返回一个reference的指向,这个一般情况我们都会写一个const的也会写一

  • Java中多线程与并发_volatile关键字的深入理解

    一.volatile关键字 volatile是JVM提供的一种轻量级的同步机制,特性: 1.保证内存可见性 2.不保证原子性 3.防止指令重排序 二.JMM(Java Memory Model) Java内存模型中规定了所有的变量都存储在主内存中(如虚拟机物理内存中的一部分),每条线程还有自己的工作内存(如CPU中的高速缓存),线程的工作内存中保存了该线程使用到的变量到主内存的副本拷贝,线程对变量的所有操作(读取.赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量.不同线程之间无法直接访

随机推荐