zoukankan      html  css  js  c++  java
  • 线程同步——用户模式下线程同步——Interlocked实现线程同步

      1 线程同步分为用户模式下的线程同步和内核对象的线程同步。
      2 
      3 当然用户模式下的线程同步实现速度比内核模式下快,但是功能也有局
      4 
      5  
      6 
      7 
      8 //1.利用原子访问:  Interlocked系列函数,关于Interlocked系列函数,我需要知道的是他们,执行的极快
      9 
     10 //(1)首先是InterlockedExchangeAdd兄弟函数,
     11 //第一个参数 Addend 代表进行操作数的地址,
     12 //第二个参数 Value 代表增加的值,如果是想进行减法,传负数即可
     13 
     14 LONG InterlockedExchangeAdd( 
     15     LONG volatile *Addend,  
     16       LONG Value ) ;
     17 
     18 LONG InterlockedExchangeAdd64(
     19     LONG64 volatile *Addend, 
     20     LONG64 Value );
     21 //(2)还有其它3个Interlocked函数
     22 
     23 LONG InterlockedExchange( 
     24     LONG volatile *Target, 
     25     LONG Value ) ;
     26 
     27 LONGLONG InterlockedExchange64(
     28     LONG64 volatile *Target, 
     29     LONG64 Value );
     30 
     31 PVOID InterlockedExchangePointer( 
     32     PVOID volatile *Target, 
     33     PVOID Value );
     34 
     35 //InterlockedExchange 和 InterlockedExchangePointer 
     36 //会把第一个参数所指向的内存地址的当前值,以原子方式替换为第二个参数指定的值
     37 
     38 //(3)最后的另个Interlocked交换函数
     39 PLONG InterlockedCompareExchange( 
     40 LONG volatile *Destination,
     41 LONG Exchange, 
     42 LONG Comperand ) ;
     43 
     44 PLONG InterlockedCompareExchangePointer(
     45 PVOID volatile *Destination, 
     46 PVOID Exchange,
     47 PVOID Comperand ) ;
     48 //函数执行的伪代码
     49 {
     50 if (Destination == Comperand )
     51 {
     52 Destination = Exchange ;
     53 }
     54 }
     55 //函数会将当前值Destination与参数Comparand进行比较,如果两个值相同,
     56 //那么函数会将*Destination 修改为Exchange,否则Destination保值不变
     57 
     58 //实现旋转锁时,InterlockedExchange及其有用
     59 //下面演示一下旋转锁
     60 BOOL g_fResourceInUse = FALSE   ;
     61 void Func1()
     62 {
     63     //等待接收资源
     64     while(InterlockedExchange(&g_fResourceInUse,TRUE) == TRUE )
     65         Sleep(0);
     66 
     67     //接收资源
     68 
     69     //我们不在需要接收资源
     70     InterlockedExchange(&g_fResourceInUse,FALSE) ;
     71 }
     72  
     73 
     74 
     75 #include "windows.h"
     76 #include "iostream"
     77 using namespace std;
     78 long g_x = 0 ;
     79 
     80 //定义线程函数1
     81 DWORD WINAPI ThreadFunOne(PVOID pvParam) ;
     82 
     83 //定义线程函数2
     84 DWORD WINAPI ThreadFunTwo(PVOID pvParam);
     85 
     86 int main()
     87 {
     88     //创建线程1
     89     HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);
     90     CloseHandle(hThreadOne);
     91 
     92     //创建线程2
     93     HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL);
     94     CloseHandle(hThreadTwo);
     95 
     96     //让主线程先挂起,确保其它线程执行完成
     97     Sleep(10000); 
     98     cout<<g_x<<endl;
     99     return 0 ;
    100 }
    101 
    102 DWORD WINAPI ThreadFunOne(PVOID pvParam) 
    103 {
    104     InterlockedExchangeAdd(&g_x,1) ;
    105     return 0;
    106 }
    107 
    108 DWORD WINAPI ThreadFunTwo(PVOID pvParam)
    109 {
    110     InterlockedExchangeAdd(&g_x,1) ;
    111     return 0;
    112 }
    113  
    114 
    115 限性,所以我们在利用线程同步时应先考虑用户模式下的线程同步
  • 相关阅读:
    关于webpack require.context() 的那点事
    微信支付服务商开发相关的那点事
    关于apache 开启 ssl https 支持 TLS1.2 的些事
    d2-admin中那些不错的技巧
    前端mock数据的几种方式
    vue pc端网站项目开发坑点与难度记录
    vue单页应用中 返回列表记住上次滚动位置、keep-alive缓存之后更新列表数据 那点事
    事务
    DBUtils和连接池
    jsp
  • 原文地址:https://www.cnblogs.com/yfyzy/p/3916173.html
Copyright © 2011-2022 走看看