C++多线程中用临界区控制全局变量的访问冲突问题
2013-12-20 00:48
429 查看
使用C++有段时间了,但是一直忙于项目,没有关注过多线程相关知识,前几天帮同学处理一个多线程的bug时花费了很多时间,终下定决心最近搞定这个问题。
关于临界区使用在前面一篇文章《C++多线程编程简单实例》中略有提及,此篇转摘的文章更为详细一些。
Original URL: http://beyondjhf-2008.iteye.com/blog/679141
困扰了我很长时间的多线程访问全局变量今天终于解决了,所以得记录一下。。控制全局变量的方法很多,有信号量、临界区等。。这里我记录一个用临界区控制访问冲突的例子。。非常好用。。
#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的票号
}
关于临界区使用在前面一篇文章《C++多线程编程简单实例》中略有提及,此篇转摘的文章更为详细一些。
Original URL: http://beyondjhf-2008.iteye.com/blog/679141
困扰了我很长时间的多线程访问全局变量今天终于解决了,所以得记录一下。。控制全局变量的方法很多,有信号量、临界区等。。这里我记录一个用临界区控制访问冲突的例子。。非常好用。。
#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的票号
}
相关文章推荐
- C++使用临界区来控制多线程访问同一个变量
- C++使用临界区来控制多线程访问同一个变量
- C++使用临界区(互斥体)来控制多线程访问同一个变量(经典例子)
- c++多线程操作全局变量的锁的问题
- c++多线程操作全局变量的锁的问题
- 【温故知新C/C++】c++全局变量定义问题||sprintf||rand()
- 2017.2.22 多线程访问成员变量造成的问题及改正
- 利用局部变量解决多线程访问问题
- C++那些细节--extern关键字&&全局变量定义问题
- 多线程调试如果遇到访问冲突尤其是堆问题,最好重启机器
- 对“C++添加一个头文件和extern以及全局变量和局部变量问题”的解释
- C++ 全局变量不明确与 using namespace std 冲突
- java多线程访问同一变量及简单同步问题(待后续整理)
- 多线程操作全局变量的问题(有点复杂,需要考虑线程的优先级问题)
- c++中的局部变量和全局变量重名时取值问题
- C/C++全局变量和局部变量作用域问题
- C++全局变量初始化引发的问题
- C++中线程函数中方访问成员变量的问题
- 面试常问问题:银行网上支付项目中怎么控制多线程高并发访问?
- c++ 全局变量的内存分配问题