精华内容
下载资源
问答
  • delphi XE多线程同步对象及其管理 本下载解决delphiXE在处理多线程时,如何对各线程进行管理、如何做到中途中断执行多线程时的线程安全,如何在多线程内部进行UI同步等等。 直接上代码,自己看咯: unit ...

    delphi XE多线程同步对象及其管理

            本下载(以下面得代码为准)解决delphiXE在处理多线程时,如何对各线程进行管理、如何做到中途中断执行多线程时的线程安全,如何在多线程内部进行UI同步等等。

            直接上代码,自己看咯:

    unit uMultiThreadSyncObjs;
    
    interface
    
    uses
      System.SysUtils,
    
      System.Types,
        //:任何一个应用系统自动加入的,其中含多线程同步等待及异步结果接口
      System.UITypes,
      System.Classes,
        //:任何一个应用系统自动加入的,其中含部分多线程类型的实现
    
      System.Variants,
    
      System.SyncObjs, //:需要用到多线程同步对象时
    
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.ScrollBox, FMX.Memo;
    
    type
      TfmxMultiThreadAndAsynResult = class(TForm)
        btnIAsyncResultAndMultiWaitEventIm: TButton;
        Text_Tips: TText;
        RectText_Tips: TRectangle;
        MetropolisUIBlue_touch: TStyleBook;
        Memo1: TMemo;
    
        ///<summary>用于并发测试的方法:</summary>
        procedure btnIAsyncResultAndMultiWaitEventImClick(Sender: TObject);
        ///<summary>用户退出窗体时,再次确认线程安全(因各线程内执行的任务太多、太快):</summary>
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
    
      private
    
        ///<summary>多线程的标识及管理数组</summary>
        LThreads :TArray<TThread>;
        ///<summary>多线程的信号灯数组</summary>
        LEvents :TArray<TEvent>;
    
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      FRestTimeout:Integer =1000;
      fmxMultiThreadAndAsynResult: TfmxMultiThreadAndAsynResult;
    
    implementation
      uses System.Math;
    {$R *.fmx}
    
    procedure TfmxMultiThreadAndAsynResult.btnIAsyncResultAndMultiWaitEventImClick(
      Sender: TObject);
    //:用于并发测试的方法:
    var
      LThreadCounts:Cardinal;
      LStopOrStart:ShortInt;
      LTest :Integer;
    begin
      if btnIAsyncResultAndMultiWaitEventIm.Text.Trim='开始' then
      begin
        btnIAsyncResultAndMultiWaitEventIm.Text:='停止';
        LStopOrStart:=0;
      end else
      begin
        btnIAsyncResultAndMultiWaitEventIm.Text:='开始';
        LStopOrStart:=1;
      end;
      if LEvents=nil then
      begin
        SetLength(LEvents,51);  SetLength(LThreads,51);
          //:初始化多线程数组及其信号灯数组
      end;
      LTest :=0;
    
      for LThreadCounts := 1 to 50 do
      begin //:开50个单线程组成的多线程
        if LEvents[LThreadCounts]=nil then
          LEvents[LThreadCounts]:=TEvent.Create(false);
          //:为多线程中的每个线程设置其执行信号灯
    
        LThreads[LThreadCounts]:=  //:在这样来识别和管理匿名多线程(线程数组)
        TThread.CreateAnonymousThread(
          //:创建一个独立的匿名线程线程,在其中完成UI界面交互的同步过程
        procedure
          var LEventsCount: Cardinal;//:线程内的变量:
        begin //匿名线程的Excute代码:
          while true do  //:让每个匿名线程无限的并发测试下去:
          begin
            System.TMonitor.TryEnter(Sender);
            TThread.Sleep(FRestTimeout); //:模拟一个后台或远程服务器的耗时操作
              //:如果是返回远程服务器的响应对象祖先类为AObject,响应对象也需以下类似的方式同时释放掉
              //:同时响应对象用TMonitor.Enter(AObject);监视try 执行...Finally TMonitor.Exit(AObject);
            System.TMonitor.Exit(Sender);
            System.SyncObjs.TInterlocked.Increment(LTest);
            if LStopOrStart=0 then
            begin
              TThread.Synchronize(nil,
              procedure begin
                Text_Tips.Text:=LTest.ToString;
              end );
              if LEvents[LThreadCounts]<>nil then
              begin
                if LEvents[LThreadCounts].WaitFor(0)=TWaitResult.wrSignaled then
                begin
                  LEvents[LEventsCount].SetEvent; //:点亮某线程的信号灯数组,停止该线程
                  LEvents[LEventsCount].DisposeOf;//:信号灯数组中的该信号灯内存空间释放
                end;
              end;
            end;
            if LStopOrStart=1 then //:用户点停止,中断操作
            begin
              for LEventsCount := 1 to 50 do
              begin
                if LEvents[LEventsCount]<>nil then
                begin
                  System.TMonitor.TryEnter(Text_Tips);
                  if LEvents[LThreadCounts].WaitFor(0)=TWaitResult.wrTimeout then
                    begin
                      LEvents[LEventsCount].SetEvent; //:点亮某线程的信号灯数组,停止该线程
                      LEvents[LEventsCount].DisposeOf;//:信号灯数组中的该信号灯内存空间释放
                    end;
                  end;
                  System.TMonitor.Exit(Text_Tips);
              end;
              if LEvents<>nil then LEvents:=nil;  //:信号灯数组内存指针释放
              exit; //:停止执行
            end;
          end;
        end ); //:匿名线程预定义,非立即执行方式:
        //LThreads[LThreadCounts].FreeOnTerminate:=true;//:设定匿名多线程,中止时立即释放
        LThreads[LThreadCounts].Start; //:开始执行匿名的多线程
      end;
    
    end;
    
    procedure TfmxMultiThreadAndAsynResult.FormClose(Sender: TObject;
      var Action: TCloseAction);
    var LThreadCounts:Cardinal;
    begin
      //用户退出窗体时,再次确认线程安全(因各线程内执行的任务太多、太快):
      if LEvents<>nil then //:如果标识多线程的信号灯数组内存指针尚未得以释放
      begin
        System.TMonitor.TryEnter(self);
        for LThreadCounts := 1 to 50 do
        begin
          if LEvents[LThreadCounts]<>nil then
          begin
            if LEvents[LThreadCounts].WaitFor( Cardinal(Ceil(FRestTimeout*0.025)) )
              =TWaitResult.wrTimeout then
            begin
              //:Waitfor多长时间:根据CPU硅晶片信号量,约线程
                //:Excute或TNetHttpClient超时时间N的千分之23-26‰之间即可
                //:一般超时时间超过2000毫秒对用户就很不友好啦:可将其作为Timeout临界值Max
              //:取N* 25‰就好
              LEvents[LThreadCounts].SetEvent;   //:点亮某线程的信号灯数组,停止该线程
              LEvents[LThreadCounts].DisposeOf;  //:信号灯数组中的该信号灯内存空间释放
            end;
    
          end;
        end;
        LEvents:=nil;          //:信号灯数组释放内存指针(地址)
        LThreads:=nil;         //:多线程数组释放内存指针(地址)
        System.TMonitor.Exit(self);
      end;
    
      close;
    end;
    
    end.
    program ProMultiThreadSyncObjs;
    
    uses
      System.StartUpCopy,
      FMX.Forms,
      uMultiThreadSyncObjs in 'uMultiThreadSyncObjs.pas' {fmxMultiThreadAndAsynResult};
    
    {$R *.res}
    
    begin
      ReportMemoryLeaksOnShutdown := True; //:只要有内存泄漏就报
    
      Application.Initialize;
      Application.CreateForm(TfmxMultiThreadAndAsynResult, fmxMultiThreadAndAsynResult);
      Application.Run;
    end.

    1、大家都要好好学习delphi XE线程同步对象单元System.SyncObjs

            https://blog.csdn.net/pulledup/article/details/106136991

    2、线程、多线程、同步执行、异步执行、并行相关内容参考

            https://blog.csdn.net/pulledup/article/details/105617706

    喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

    展开全文
  • 再谈delphi XE多线程同步对象及其管理二 前言:不精通线程、不擅长对多线程进行管理,就不可能在当今多CPU多核心的年代写出优秀的程序代码,软件的性能将会大打折扣。本文及其示例代码,诠释System.Classes.pas...

    再谈delphi XE多线程同步对象及其管理二

     

     

    前言:不精通线程、不擅长对多线程进行管理,就不可能在当今多CPU多核心的年代写出优秀的程序代码,软件的性能将会大打折扣。本文及其示例代码,诠释System.Classes.pas中的(多)线程 和System.SyncObjs.pas (深入应用(多)线程时涉及的同步对象),System.Threading.pas线程、线程池、未来、任务及并行库的原理与应用。讲解了线程执行函数的最大响应时间(及设定的超时时间)、并发执行的线程数、CPU的核心数等,对线程池、最大工作线程、实际工作线程、空闲工作线程、CPU使用数、平均CPU使用数等性能指标的影响。还描述了线程在何时执行完毕,线程在何时进行释放,线程执行完毕是否等于线程得到释放,怎样通过代码控制线程的执行,怎样通过代码将线程彻底释放。期待对各位同学和同事有所帮助。

    一、直接上代码

           代码执行的效果展示PC端:https://www.cpuofbs.com/app/samples/ThreadsAndCpu/ThreadsAndCpu.swf.html

           代码执行的效果展示手机端:https://www.cpuofbs.com/app/samples/ThreadsAndCpu/ThreadsAndCpu.flv

    unit uMultiThreadSyncObjs;
    
    interface
    
    uses
      System.SysUtils,
    
      System.Types,
        //:任何一个应用系统自动加入的,其中含多线程同步等待及异步结果接口
      System.UITypes,
      System.Classes,
        //:任何一个应用系统自动加入的,其中含部分多线程类型的实现
    
      System.Variants,
    
      System.SyncObjs, //:需要用到多线程同步对象时
      System.Threading,
    
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.ScrollBox, FMX.Memo,
      FMX.Edit, FMX.Layouts;
    
    type
      TfmxMultiThreadAndAsynResult = class(TForm)
        btnIAsyncResultAndMultiWaitEventIm: TButton;
        Text_Tips: TText;
        RectText_Tips: TRectangle;
        MetropolisUIBlue_touch: TStyleBook;
        Memo1: TMemo;
        Button1: TButton;
        Layout1: TLayout;
        Label1: TLabel;
        Edit1: TEdit;
    
        ///<summary>用于并发测试的方法:</summary>
        procedure btnIAsyncResultAndMultiWaitEventImClick(Sender: TObject);
        ///<summary>用户退出窗体时,再次确认线程安全(因各线程内执行的任务太多、太快):</summary>
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure Button1Click(Sender: TObject);
        procedure Edit1Change(Sender: TObject);
    
      private
    
        ///<summary>多线程的标识及管理数组</summary>
        LThreads :TArray<TThread>;  LmyThreadsID:TArray<Cardinal>;
        ///<summary>多线程的信号灯数组</summary>
        LEvents :TArray<TEvent>;
        procedure StopMe(Sender: TObject);
    
    
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      FRestTimeout:Integer =1000;
      //:20000: 超长时测试 1000: 长时测试 500: 中短时时测试 ;
      //:200: 短时测试 100: 短时测s试 10: 短时测试  5: 超短时测试
      LStopOrStart:ShortInt =1;
      LTest :Integer =0;
      LWorkerEvent:TProc;
      fmxMultiThreadAndAsynResult: TfmxMultiThreadAndAsynResult;
    
    implementation
      uses
        System.Math,
        uMultiThreadSyncObjs_1;
    {$R *.fmx}
    
    procedure TfmxMultiThreadAndAsynResult.btnIAsyncResultAndMultiWaitEventImClick(
      Sender: TObject);
    //:用于 多个单线程并发测试的方法:
    var
      LThreadCounts:Cardinal;
    begin
      if LEvents=nil then
      begin
        SetLength(LEvents,51);  SetLength(LThreads,51);
          //:初始化多线程数组及其信号灯数组
      end;
      if LStopOrStart=1 then
      begin
        btnIAsyncResultAndMultiWaitEventIm.Text:='停止';
        DEC(LStopOrStart);
      end else
      begin
        btnIAsyncResultAndMultiWaitEventIm.Text:='开始';
        INC(LStopOrStart);
      end;
      if not Assigned(LWorkerEvent) then
        LWorkerEvent:=
        procedure
          var LEventsCount: Cardinal;//:线程内的变量:
        begin //匿名线程的Excute代码:
          while LStopOrStart=0 do  //:让每个匿名线程无限的并发测试下去:
          begin
            TThread.Sleep(FRestTimeout); //:模拟一个后台或远程服务器的耗时操作
              //:如果是返回远程服务器的响应对象祖先类为TObject,响应对象如果下面需要与UI同步:
              //:则它们在被强行关闭时须用监视器加锁TMonitor.Enter(AObject);TMonitor.Exit(AObject);
            if LStopOrStart=1 then //:用户点停止,中断操作
            begin
              for LEventsCount := 1 to 50 do
              begin
                if LEvents[LEventsCount]<>nil then
                begin
                  if LEvents[LThreadCounts].WaitFor( 0 )
                    =TWaitResult.wrTimeout then
                  begin
                    LEvents[LEventsCount].SetEvent; //:点亮某线程的信号灯数组,停止该线程
                    LEvents[LEventsCount].DisposeOf;//:信号灯数组中的该信号灯内存空间释放
                  end;
                end;
              end;
              if LEvents<>nil then LEvents:=nil;  //:信号灯数组内存指针释放
    
              exit;  //:停止继续执行并跳出while循环调用者   //}
            end;
            if LStopOrStart=0 then //:用户点的是开始
            begin                  //ForceQueue  Synchronize 上锁,强制队列:
              System.SyncObjs.TInterlocked.Increment(LTest);
              //TThread.ForceQueue(TThread.Current, //nil,
              TThread.Synchronize(TThread.Current,//nil,
              procedure begin
                Text_Tips.BeginUpdate;
                  Text_Tips.Text:=LTest.ToString;
                Text_Tips.EndUpdate;
    
                memo1.BeginUpdate;
                  if memo1.Lines.Count>100 then memo1.Lines.Clear;
                  //memo1.Lines.Add('当前CPU总数:'+TThread.ProcessorCount.ToString);
                  //if not memo1.Lines.Text.Contains(LmyThreadsID[Cardinal(LThreadCounts)].ToString) then
                  begin
                    //memo1.Lines.Add('当前线程ID:'+LmyThreadsID[Cardinal(LThreadCounts)].ToString);
                    memo1.Lines.Add('当前线程池最大工作线程数:'+TThreadPool.Current.MaxWorkerThreads.ToString);
                    memo1.Lines.Add('当前工作线程数:'+TThreadPoolStats.Current.WorkerThreadCount.ToString);
                    memo1.Lines.Add('当前空闲工作线程数:'+TThreadPoolStats.Current.IdleWorkerThreadCount.ToString);
                    memo1.Lines.Add('当前CPU使用数:'+TThreadPoolStats.Current.CurrentCPUUsage.ToString);
                    memo1.Lines.Add('当前平均CPU使用数:'+TThreadPoolStats.Current.AverageCPUUsage.ToString);
                  end;
                memo1.EndUpdate;
    
                //if Edit1.Enabled<>false then Edit1.Enabled:=false;
              end );
              if LEvents[LThreadCounts]<>nil then
              begin
                if LEvents[LThreadCounts].WaitFor(0)=TWaitResult.wrSignaled then
                begin
                  LEvents[LEventsCount].SetEvent; //:点亮某线程的信号灯数组,停止该线程
                  LEvents[LEventsCount].DisposeOf;//:信号灯数组中的该信号灯内存空间释放
                end;
              end;
            end;
          end;
    
        end ;
    
      SetLength(LmyThreadsID,51);
      for LThreadCounts := 1 to 50 do
      begin //:开1200个单线程组成的多线程
        LmyThreadsID[Cardinal(LThreadCounts)]:=Cardinal(LThreadCounts);
        if LEvents[LThreadCounts]=nil then
          LEvents[LThreadCounts]:=TEvent.Create(false);
          //:为多线程中的每个线程设置其执行信号灯
        TThreadPool.Current.QueueWorkItem(LWorkerEvent);
        LThreads[LThreadCounts]:= //:在这样来识别和管理匿名多线程(线程数组)
        TThread.CreateAnonymousThread(
          //:创建一个独立的匿名线程线程,在其中完成UI界面交互的同步过程
          LWorkerEvent );
          //:匿名线程预定义,非立即执行方式:
    
        if LThreads[LThreadCounts]<>nil then
          LThreads[LThreadCounts].Start; //:开始执行匿名的多线程
      end;
    end;
    
    procedure TfmxMultiThreadAndAsynResult.StopMe(Sender: TObject);
    var LThreadCounts:Cardinal;
    begin
      if LEvents<>nil then //:如果标识多线程的信号灯数组内存指针尚未得以释放
      begin
        if LStopOrStart=0 then btnIAsyncResultAndMultiWaitEventImClick(Sender);
          //:如果处于运行状态就先点 停止,然后释放所有运行线程的内存:
        System.TMonitor.TryEnter(Text_Tips); Text_Tips.Locked:=true;
        System.TMonitor.TryEnter(btnIAsyncResultAndMultiWaitEventIm); btnIAsyncResultAndMultiWaitEventIm.Locked:=true;
        for LThreadCounts := 1 to 50 do
        begin
          if LEvents[LThreadCounts]<>nil then
          begin
            if LEvents[LThreadCounts].WaitFor( Cardinal(Ceil(FRestTimeout*0.025)) )
              =TWaitResult.wrTimeout then
            begin
              //:Waitfor多长时间:根据CPU硅晶片信号量,约线程:
                //:Excute或TNetHttpClient超时时间N的千分之23-26‰之间即可
                //:一般超时时间超过2000毫秒对用户就很不友好啦:可将其作为Timeout临界值Max
              //:取N* 25‰就好
              LEvents[LThreadCounts].SetEvent;   //:点亮某线程的信号灯数组,停止该线程
              LEvents[LThreadCounts].DisposeOf;  //:信号灯数组中的该信号灯内存空间释放
            end;
          end;
        end;
        LEvents:=nil;          //:信号灯数组释放内存指针(地址)
        LThreads:=nil;         //:多线程数组释放内存指针(地址)
    
        btnIAsyncResultAndMultiWaitEventIm.Locked:=false; System.TMonitor.Exit(btnIAsyncResultAndMultiWaitEventIm);
        Text_Tips.Locked:=false; System.TMonitor.Exit(Text_Tips);
      end;
    
    end;
    
    procedure TfmxMultiThreadAndAsynResult.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      StopMe(Sender);
      close;
    end;
    
    procedure TfmxMultiThreadAndAsynResult.Edit1Change(Sender: TObject);
    var Value: Integer;
    begin
      if Edit1.Text.Trim='' then Edit1.Text:='1000';
      if TryStrToInt( Edit1.Text.Trim, Value)=true then
      begin
        FRestTimeout:=Value;
        memo1.Lines.Add('当前CPU总数:'+TThread.ProcessorCount.ToString);
      end;
    end;
    
    procedure TfmxMultiThreadAndAsynResult.Button1Click(Sender: TObject);
    begin
      if fmxMultiThreadAndAsynResult_1=nil then
        Application.CreateForm(TfmxMultiThreadAndAsynResult_1, fmxMultiThreadAndAsynResult_1);
      fmxMultiThreadAndAsynResult_1.Show;
    end;
    
    end.

    二、原理参考

    (一)、官方

    1、System.Classes.pas中的(多)线程  和System.SyncObjs.pas (深入应用(多)线程时涉及的同步对象)

    1.1、TThread 线程 http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread

    1.2、TThread.CreateAnonymousThread 匿名线程 :

    http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.CreateAnonymousThread

    1.3、System.SyncObjs.TEvent (多)线程信号灯同步对象

    1.4、TThread.Synchronize(多)线程同步过程、TThread.Queue(多)线程队列(异步)过程:

    http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.Synchronize

    http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.Queue

    1.5、其它的线程安全同步对象:详见System.SyncObjs.pas

    1.6、底层的http://docwiki.embarcadero.com/Libraries/Rio/en/System.SyncObjs.TCriticalSection线程安全临界区同步对象

    1.7、底层的System.SysUtils.TMultiReadExclusiveWriteSynchronizer (原子)多读少写(独占写)同步器

    2、System.Threading.pas

    http://docwiki.embarcadero.com/Libraries/Rio/en/System.Threading

    2.1、TThreadPool 线程池  

    2.2、IFuture  未来

    2.3、ITask 任务

    2.4、TParallel 并行库

    (二)、本博客经验谈

    1、delphiXE关于线程和多线程、线程的同步与异步执行 https://blog.csdn.net/pulledup/article/details/105617706

    2、大家都要好好学习delphi XE线程同步对象单元System.SyncObjs https://blog.csdn.net/pulledup/article/details/106136991

    3、delphi XE多线程同步对象及其管理 https://blog.csdn.net/pulledup/article/details/106150698

    4、源码示例2:delphiXE多线程同步对象及异步执行.zip https://download.csdn.net/download/pulledup/12424951 本下载解决delphiXE在处理多线程时,如何对各线程进行管理、如何做到中途中断执行多线程时的线程安全,如何在多线程内部进行UI同步等等,还可看我的上面这个第3、博文同步。

    5、本案源码:https://download.csdn.net/download/pulledup/12506035

    喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

    展开全文
  • 多线程同步对象汇总

    千次阅读 2009-03-21 12:02:00
    多线程同步对象汇总 1。包括常用的互斥锁,条件变量和读写锁,使用了c++ 的构造锁定和析构解锁的原理,能方便安全的使用。2。目前windows 只是支持临界区,linux 的都支持。3。不支持循环递归锁定,需要自己判断。...

    多线程同步对象汇总 

    1。包括常用的互斥锁,条件变量和读写锁,使用了c++ 的构造锁定和析构解锁的原理,能方便安全的使用。

    2。目前windows 只是支持临界区,linux 的都支持。

    3。不支持循环递归锁定,需要自己判断。否则会死锁。

     

     

    //头文件myosmutex.h

    #ifndef _MYOSMUTEX_H_

    #define _MYOSMUTEX_H_ 
    #ifdef WIN32
    #include <process.h>
    #include <windows.h>
    class MyOSMutex
    {
    private:
    MyOSMutex(const MyOSMutex&);
    MyOSMutex& operator=(const MyOSMutex&);
    public:
    MyOSMutex();
    ~MyOSMutex();
    void lock();
    void unlock();
    bool trylock();
    private:
    CRITICAL_SECTION m_mutex;
    };
    #else
    #include <sys/errno.h>
    #include <pthread.h>
    #include <sys/time.h>
    class CThreadCond
    {
    private:
    CThreadCond(const CThreadCond&);
    CThreadCond& operator=(const CThreadCond&);
    //
    pthread_cond_t m_cond;
    public:
    CThreadCond();
    ~CThreadCond();
    //
    template <typename T> bool wait(const T& mutex,unsigned int millisecond = 0);
    //
    bool notifyall();
    };
    class MyOSMutex
    {
    private:
    MyOSMutex(const MyOSMutex&);
    MyOSMutex& operator=(const MyOSMutex&);
    public:
    MyOSMutex();
    ~MyOSMutex();
    void lock();
    void unlock();
    bool trylock();
    private:
    pthread_mutex_t m_mutex;
    friend class CThreadCond;
    };
    class CReadWriteLock
    {
    private:
    CReadWriteLock(const CReadWriteLock&);
    CReadWriteLock& operator=(const CReadWriteLock&);
    protected:
    pthread_rwlock_t m_rwlock;
    public:
    CReadWriteLock();
    ~CReadWriteLock();
    void readlock();
    void writelock();
    void unlock();
    bool tryreadlock();
    bool trywritelock();
    };
    class CReadLock
    {
    private:
    CReadWriteLock &m_lock;
    CReadLock(const CReadLock&);
    CReadLock& operator=(const CReadLock&);
    public:
    CReadLock(CReadWriteLock &lock);
    void lock();
    void unlock();
    bool trylock();
    };
    class CWriteLock
    {
    private:
    CReadWriteLock &m_lock;
    CWriteLock(const CWriteLock&);
    CWriteLock& operator=(const CWriteLock&);
    public:
    CWriteLock(CReadWriteLock &lock);
    void lock();
    void unlock();
    bool trylock();
    };
    #endif
    template <typename T> class CAutoLock
    {
    private:
    T &m_mutex;
    CAutoLock(const CAutoLock&);
    CAutoLock& operator=(const CAutoLock&);
    private:
    void lock();
    void unlock();
    bool trylock();
    public:
    CAutoLock(T &lock);
    ~CAutoLock();
    };
    #endif 
     
     
    //cpp 文件
    #include "myosmutex.h"
    #include <assert.h>
    #include <time.h>
    template <typename T> bool CThreadCond::wait(const T& mutex,unsigned int millisecond)
    {
    int result = 0;
    if(millisecond > 0)
    {
    struct timeval tv;
    gettimeofday(&tv,0);
    struct timespec ts;
    ts.tv_sec = tv.tv_sec;
    ts.tv_nsec = tv.tv_usec * 1000;
    ts.tv_sec += (millisecond / 1000);
    ts.tv_nsec += (millisecond % 1000) * 1000000;
    result = pthread_cond_timedwait(&m_cond,&mutex.m_mutex,&ts);
    }
    else
    {
    result = pthread_cond_wait(&m_cond,&mutex.m_mutex);
    }
    return result == 0;
    }
    bool CThreadCond::notifyall()
    {
    int result = pthread_cond_broadcast(&m_cond);
    return result == 0;
    }
    MyOSMutex::MyOSMutex()
    {
    #ifdef WIN32
    ::InitializeCriticalSection(&m_mutex);
    #else
    (void)pthread_mutex_init(&m_mutex,0);
    #endif
    }
    MyOSMutex::~MyOSMutex()
    {
    #ifdef WIN32
    ::DeleteCriticalSection(&m_mutex);
    #else
    pthread_mutex_destroy(&m_mutex);
    #endif
    }
    void  MyOSMutex::lock()
    {
    #ifdef WIN32
    ::EnterCriticalSection(&m_mutex);
    #else
    (void)pthread_mutex_lock(&m_mutex);
    #endif
    }
    void  MyOSMutex::unlock()
    {
    #ifdef WIN32
    ::LeaveCriticalSection(&m_mutex);
    #else
    pthread_mutex_unlock(&m_mutex);
    #endif
    }
    bool MyOSMutex::trylock()
    #ifdef WIN32
    // Return values of this function match our API
    //#define _WIN32_WINNT 0x0500
    /*
    if(::TryEnterCriticalSection(&m_mutex) == 0)
    {  return false;
    }
    */
    #else
    int theErr = pthread_mutex_trylock(&m_mutex);
    if(theErr != 0)
    {
    assert(theErr == EBUSY);
    return false;
    }
    #endif
    return true;
    }
    CReadWriteLock::CReadWriteLock()
    {
    pthread_rwlock_init(&m_rwlock,0);
    }
    CReadWriteLock::~CReadWriteLock()
    {
    pthread_rwlock_destroy(&m_rwlock);
    }
    void CReadWriteLock::readlock()
    {
    pthread_rwlock_rdlock(&m_rwlock);
    }
    void CReadWriteLock::writelock()
    {
    pthread_rwlock_wrlock(&m_rwlock);
    }
    void CReadWriteLock::unlock()
    {
    pthread_rwlock_unlock(&m_rwlock);
    }
    bool CReadWriteLock::tryreadlock()
    {
    int result = 0;
    result = pthread_rwlock_tryrdlock(&m_rwlock);
    return result == 0?true:false;
    }
    bool CReadWriteLock::trywritelock()
    {
    int result = 0;
    result = pthread_rwlock_trywrlock(&m_rwlock);
    return result == 0?true:false;
    }
    CReadLock::CReadLock(CReadWriteLock &lock):m_lock(lock)
    {
    //
    }
    void CReadLock::lock()
    {
    m_lock.readlock();
    }
    void CReadLock::unlock()
    {
    m_lock.unlock();
    }
    bool CReadLock::trylock()
    {
    return m_lock.tryreadlock();
    }
    CWriteLock::CWriteLock(CReadWriteLock &lock):m_lock(lock)
    {
    //
    }
    void CWriteLock::lock()
    {
    m_lock.writelock();
    }
    void CWriteLock::unlock()
    {
    m_lock.unlock();
    }
    bool CWriteLock::trylock()
    {
    return m_lock.trywritelock();
    }
    template <typename T> CAutoLock<T>::CAutoLock(T &lock):m_mutex(lock)
    {
    m_mutex.lock();
    }
    template <typename T> CAutoLock<T>::~CAutoLock()
    {
    m_mutex.unlock();
    }
    //模板类中的成员函数在类外定义 
    template <typename T> bool CAutoLock<T>::trylock()
    {
    return m_mutex.trylock();
    }
    CThreadCond::CThreadCond()
    {
    pthread_cond_init(&m_cond,0);
    }
    CThreadCond::~CThreadCond()
    {
    pthread_cond_destroy(&m_cond);
    }
    展开全文
  • 事件确实可以严格控制每个线程的执行顺序,但大多数时候,每个线程都是一个单独的任务副本,...这个是的,用户级线程同步互斥对象和内核级线程同步对象所消费的资源相差还是有点大。 事件和信号量一般在线程间

    事件确实可以严格控制每个线程的执行顺序,但大多数时候,每个线程都是一个单独的任务副本,即不存在说一定要先让线程A操作公共资源再让线程B操作,B先A后也可以,只要保证公共资源不被同时改写,能正确的读写就行了。因此大多数时候临界区就可以了,事件的开销要大很多。



    这个是的,用户级线程同步互斥对象和内核级线程同步对象所消费的资源相差还是有点大。


    事件和信号量一般在线程间通信,即有数据交互的时候才会用。

    展开全文
  • 线程同步对象

    2014-05-11 13:58:09
    四种进程或线程同步互斥的控制方法 1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。  2、互斥量:为协调共同对一个共享资源的单独访问而设计的。  3、信号量:为控制一个...
  • 多线程同步:多个线程共同协作正确的执行任务。 我们经常见到多线程同步关键字synchronized,那它到底是利用谁做同步锁呢。 要想实现多线程同步,必须要保证同步锁是共享唯一的。 synchronized一般用于3中场景: ...
  • Java多线程04_线程同步问题

    万次阅读 2020-08-30 16:25:59
    Java多线程04_线程同步问题 关键字 synchronized 可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块 案例1:不安全的买票 (多个线程访问同一个对象的同一个方法): public class ByTicket { public ...
  • 多线程同步之互斥对象

    千次阅读 2015-06-25 20:06:38
    多线程同步之互斥对象 作者:vpoet mail:18200268879@163.com 在http://blog.csdn.net/u013018721/article/details/46637215一文中介绍了使用临界区 对卖票问题进行线程间同步,本文将在上文...
  • 原文地址:多线程实现线程同步~~临界区对象 - CSDN博客 http://blog.csdn.net/qq_25425023/article/details/45253237 多线程实现线程同步~~临界区对象  线程同步是指同一进程中的多个线程互相...
  • 上一篇说明了多线程是存在着问题的,起始就是多线程操作同一数据而不同步的问题。那么如果实现线程的同步呢?... 我们先用互斥内核对象实现线程同步。    互斥内核对象,能够确保线程拥有对单个资源
  • MFC多线程临界区对象实现线程同步范例 // vs23_5_5.cpp : 定义控制台应用程序的入口点。 //txwtech 2019/03/26 vs2010平台 #include "stdafx.h" #include "windows.h" DWORD WINAPI ThreadProc1(LPVOID lpParam);...
  • Java多线程-线程同步对象锁)

    千次阅读 2015-08-26 16:54:23
    Java线程同步是用来解决线程间共享资源的。在传统的单线程程序中,程序都是有序的按照程序猿写好的指定的流程运行的,因此对于一些资源,比如某个变量的内存读写顺序是固定的,因此不会出现问题。  但是在多线程...
  • 多线程的情况下,如果存在多个线程要...MFC 提供的多线程类分为两类:同步对象(CSyncObject 、CSemaphore 、CMutex 、CCriticalSection 和 CEvent )和同步访问对象(CMultiLock 和CSingleLock )。 当
  • synchronized在多线程中的应用2008-11-05 15:13先看一个例子://模仿火车售票系统,假设有4个售票点同时售票,我们可以把四个售票点定义为四个独立线程class Test{public static void main(String[] args) { ...
  • 事件对象是指在程序中使用内核对象的有无信号状态实现线程同步。 1.使用API函数操作事件对象 API函数为CreateEvent; 函数原型为: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SD ...
  • Java多线程同步中的类对象和类的实例对象对象:一个类的静态成员域和静态成员方法隶属于类对象 类的实例对象:一个类的非静态成员域和非静态成员方法隶属于类的实例对象 所以,在多线程同步中,同步方法的锁就很...
  • 秒杀多线程第六篇 经典线程同步 事件Event

    万次阅读 多人点赞 2012-04-11 09:06:57
    阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇 一个经典的多线程同步问题》《秒杀多线程第五篇 经典线程同步关键段CS》 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权”特性...
  • 互次对象实现线程同步。 1.使用API函数操作互次对象。 函数CreateMutex用于创建并返回互次对象。 函数原型: HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD BOOL bInitialOwner, // ...
  • C++多线程同步(采用事件对象Event)

    千次阅读 2016-11-25 12:07:11
    C++多线程同步(采用事件对象Event)
  • 线程1的函数获取互斥对象的拥有权(并未释放拥有权),接着切换CPU时间片,进入到了线程2函数的WaitForSingleObject,然后调用了线程2函数的 cout;,这是怎么一回事呢,线程1函数还未释放拥有权,线程2函数怎么还能...
  • C++多线程同步(采用互斥对象Mutex)
  • 多线程程序框架-利用互斥对象实现线程同步
  • 线程同步 Critical section(临界区)用来实现“排他性占有”。适用范围是单一进程的各线程之间。它是: · 一个局部性对象,不是一个核心对象。 · 快速而有效率。 · 不能够同时有一个以上的cri
  • MFC互斥对象实现多线程同步实例 // vs23_5_9.cpp : 定义控制台应用程序的入口点。 //txwtech #include "stdafx.h" #include "windows.h" DWORD WINAPI ThreadProc1(LPVOID lpParam); DWORD WINAPI ThreadProc2...
  • 接着上一篇文章我们继续讨论多线程的问题,这一次我们利用互斥对象(mutex)来解决火车站售票同步问题。 1 利用互斥对象实现线程同步 互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。...
  • 1)是某个对象实例内,synchronized aMethod(){}可以防止线程同时访问这个对象的synchronized方法(如果一个对象个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问...
  • 多线程操作时,上篇博客写到了两种不同方式的线程同步方式: 方式1:同步代码块 一般写在方法内部,如:synchronized (任意对象名){ ...//同步代码块 }方式2:同步方法 用synchronized或者static synchronized来...
  •  一、互斥对象和事件对象属于内核对象,利用内核对象进行线程同步,速度较慢,但可以实现在个进程中各线程间进行同步。  二、关键代码段式工作在用户方式下,同步速度较快,但在使用关键代码段时,很容易进入...
  • windows多线程同步之事件对象

    千次阅读 2015-08-17 10:15:26
    引子:有这样一个程序需求,做一个文本编辑器,读取文件内容后能够进行文字拼写检查...看到上面的需要,第一眼我们的反应是用多线程可以解决,针对该程序,利用事件内核对象将比较容易的实现。下面给出代码: #in

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,734
精华内容 5,893
热门标签
关键字:

多线程同步对象