C++多线程中用临界区控制全局变量的访问冲突问题

困扰了我很长时间的多线程访问全局变量今天终于解决了,所以得记录一下。。控制全局变量的方法很多,有信号量、临界区等。。这里我记录一个用临界区控制访问冲突的例子。非常好用。

#include <windows.h>
#include <iostream>
using namespace std;
//首先做两个线程,实现两个线程间的同步 上次是利用互斥对象实现线程间的同步CreateMutex函数和事件对象间的同步CreateEvent函数,这次用关键代码段(临界区对象)来实现
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);                

int tickets=100;
CRITICAL_SECTION g_cs;                                  //1.定义一个临界区对象 

void main()
{
  HANDLE hThread1;
  HANDLE hThread2;
  hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
  CloseHandle(hThread1);
  CloseHandle(hThread2);                                

  InitializeCriticalSection(&g_cs);                     //2.初始化临界对象
  Sleep(4000);
  DeleteCriticalSection(&g_cs);                         //3.当函数要结束的时候释放所有没有被拥有的临界区对象相关的成员
} 

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{                                                               

while(TRUE)
{
EnterCriticalSection(&g_cs);                    //4.判断是否有线程在访问公共资源,如果有线程正在访问就,不能执行下面的
if(tickets>0)
{
Sleep(1);
cout<<"Thread1 sell tickets:"<<tickets--<<endl;
}
else
break;
LeaveCriticalSection(&g_cs);                    //5.执行完代码段的就离开临界区,那么下个线程就可以访问资源了,这就好像我们要用公用电话(共有资源),我们必须先看看电话厅里是否有人,有人就不能此时用,没人就可以用这个资源了
}
//7.注意一定要释放,否则线程2就没有执行的机会 “谁拥有谁释放”
return 0;
}                                                          

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{ 

while(TRUE)
{
EnterCriticalSection(&g_cs);
if(tickets>0)
{
Sleep(1);
cout<<"Thread2 sell tickets:"<<tickets--<<endl;
}
else
break;
LeaveCriticalSection(&g_cs);                    //8.我们可以将线程2注释起来看看,运行发现,线程1卖出第100张后不再卖了,其余的都是线程2卖的                         

}
return 0;                                          //6.程序这样执行,同步建立了。没有出现重复和0的票号                      

}   

原文地址:https://www.cnblogs.com/rainbow70626/p/10175623.html

时间: 2024-11-03 21:51:15

C++多线程中用临界区控制全局变量的访问冲突问题的相关文章

C++拾遗--多线程:临界区解决子线程的互斥

C++拾遗--多线程:临界区解决子线程的互斥 前言 为了解决子线程的互斥问题,windows系统提出了关键段或临界区(CRITICAL_SECTION)的概念.它一共有四个共两对操作:初始化.销毁,进入.离开.它们定义在头文件synchapi.h中. 1.初始化变量 VOID WINAPI InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); 2.销毁变量 VOID WINAPI DeleteCriticalSect

多线程顺序的控制(wait,notity,sleep)

public class abc extends Thread{    private Object prev=null;    private Object self=null;    private String msg=null;    public abc(Object prev,Object self,String msg){        this.prev=prev;        this.self=self;        this.msg=msg;    }    publi

QlikView中用按钮控制转换图表类型(比如条形图转成垂直表)

QlikView中的图表中可以通过勾选某些配置就可以很方便的进行图表类型转换,让用户可以在图表上面选择是要看条形图或者柱状图或者垂直图等detail数据. 在Fast Type Change中选中如上图所示的选项之后,图表的右上角多了一个Fast Change选项,变成下面这样: 因为在第一幅图里面的右下角Preferred Icon勾选的是In Caption,因此该控制Chart Type Fast Change的按钮在标题栏,假如勾选第一个In Chart的话,效果如下所示: 由于Dash

【转】Java多线程操作局部变量与全局变量

原文网址:http://blog.csdn.net/undoner/article/details/12849661 在这篇文章里,我们首先阐述什么是同步,不同步有什么问题,然后讨论可以采取哪些措施控制同步,接下来我们会仿照回顾网络通信时那样,构建一个服务器端的“线程池”,JDK为我们提供了一个很大的concurrent工具包,最后我们会对里面的内容进行探索. 为什么要线程同步? 说到线程同步,大部分情况下, 我们是在针对“单对象多线程”的情况进行讨论,一般会将其分成两部分,一部分是关于“共享变

多线程相关------临界区CriticalSection

多线程一直是短板,整理相关知识方便查询 临界区(Critical Section) 临界区是一段供线程独占式访问的代码.在任意时刻,若有一个线程正在访问该代码段,如果其他所有试图访问的线程都将被挂起,直到访问的线程离开该代码段才可进入,保证线程安全. 适用于控制数据访问. 因其线程所有权其可以用于线程间互斥,而不能用于同步. 相关函数 InitializeCriticalSection初始化临界区对象 void WINAPI InitializeCriticalSection( _Out_ LP

多线程并发流程控制之dispatch_group 有关函数

A B C D 4个并发下载任务,怎样在第一时间知道任务全部完成? dispatch_group 可以帮我们实现这样的控制. 上代码,看说明. [objc] view plain copy dispatch_group_t group = dispatch_group_create(); // 某个任务放进 group dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ // 任务代码1 }); dispatch_gro

springboot使用多线程调用接口控制层

同样是拿别人的,整体没报错,不过还未经具体测试配置类: package com.tansuo365.test1.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; import org.springframe

Java多线程系列四——控制线程执行顺序

假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatch类:指定计数器,当计数器清零即取消阻塞 import java.util.concurrent.CountDownLatch; import org.junit.Assert; import org.junit.Test; /** * @Description: 规定线程次序的方法 */ publ

Volatile 多线程中用到的关键字

Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值. Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比. 这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化. 而volatile关键字就是提示VM:对于这个成员变量不