且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

以关键代码段为例子详细讲解多线程中的同步技术

更新时间:2022-08-13 08:35:59

    说线程就要说到进程每一个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(&section);//进入关键代码段,取得临界区对象所有权
         数据的执行代码放在这里.........
    LeaveCriticalSection(&section);//释放临界区对象所有权 

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); ;
}

 

 

 

 

       

 \