以关键代码段为例子详细讲解多线程中的同步技术
说线程就要说到进程每一个exe文件运行的时候 系统就会为这个进程分配虚拟空间 ,多个进程在逻辑上重复使用该空间 。
线程实际上是程序真正的功能实现者,一个进程包含多个线程 ,线程之间相互协作共同完成一项任务 。
每个进程中的多个线程可以共享进程中的数据 。 每个进程都有一个唯一称为主线程的线程,例如mian()函数所在的线程就是主线程 。
有些CPU只支持单线程技术 但是我们仍然可以使用多线程是因为 操作系统给每个线程分配了 一个时间片 这个时间片很短 因此在一个线程的时间片到期的时候
另一个线程立马执行 ,就让我们感觉到好像实现了多线程 。。。。。
什么是线程同步呢? 如何利用临界资源实现线程同步?
既然是多个线程并发执行那么为什么我们须要线程的同步呢,下面我做一个比方 。 如果我们去买衣服 我们在换衣间换衣服的时候别人是不能进来换的 。
必须要等 到我们换完衣服之后下一个人才可以进来 。相对于进程也是一个 一个进程中的多个线程 在执行着不同的功能 ,
例如:进程中有 线程A B , A对一个数据进行读取 ,B对同一个数据进行存储 当然会觉得这样效率很高 ,但是一旦AB 线程 同时对 这个数据进行
读取 和存取的时候 就会因为 A B 线程同时要求同一个资源 , 而导致线程的死锁 ,这就是 操作系统上常说的线程的死锁 。。
如果死锁发生name对于我们的软件是致命的打击 。
我们可以利用一个叫做关键代码段的技术来解决这个问题 当然实现线程同步的方法有很多 我这里只讲述 利用关键代码段实现线程的同步 !
这种方法的实现思路如下 :
例如有 A B 2个线程 比如我们都要操作同一个数据 那么我们可以让这2个数据在操作之前 先来申请 一个叫做临界区的资源 ,这个资源是唯一的谁申请到
谁就有对数据的操作权可以继续执行线程 另一个线程就必须暂停等待 知道 申请到临界资源的线程 释放了临界资源之后才可以 获得临界资源从而进行 数据的操作
现在明白了吧 。。。其实很简单 ,如果还不明白不要紧看下代码就 OK了
1.声明一个 CRITICAL_SECTION s ; //临界资源
2.初始化临界资源 ::InitializeCriticalSection(&s) ; //初始化临界区资源
3.
EnterCriticalSection(§ion);//进入关键代码段,取得临界区对象所有权
数据的执行代码放在这里.........
LeaveCriticalSection(§ion);//释放临界区对象所有权
4.在退出的时候DeleteCriticalSection(&s) ;//释放初始化了的临界资源
以上就是 利用临界区实现线程同步的方法 代码如下
#include "windows.h"
#include <iostream>
using namespace std ;
int x=0 ;
CRITICAL_SECTION s ; //定义一个临界区资源 在使用完毕的时候应该删除 掉
DWORD WINAPI Thread1(
LPVOID lpParameter // thread data
)
{
while(1)
{
::EnterCriticalSection(&s);
if(x<=100)
{
cout<<"Thread1: "<<x++<<endl ;
::LeaveCriticalSection(&s);
}
else
{
LeaveCriticalSection(&s);
break;
}
}
return 0 ;
}
DWORD WINAPI Thread2(
LPVOID lpParameter // thread data
)
{
while(1)
{
::EnterCriticalSection(&s);
if(x<=100)
{
cout<<"Thread2: "<<x++<<endl ;
::LeaveCriticalSection(&s);
}
else
{
LeaveCriticalSection(&s);
break;
}
}
return 0 ;
}
void main()
{
::InitializeCriticalSection(&s) ; //初始化临界区资源
HANDLE h1,h2 ;
h1=::CreateThread(NULL,0,Thread1,0,0,NULL) ;
h2=::CreateThread(NULL,0,Thread2,0,0,NULL) ;
// ::DeleteCriticalSection(&s); //从内存中删除掉初始化好的临界区
Sleep(5000); ;
}
摘自:yue7603835的专栏
补充:软件开发 , Vc ,