Delphi Thread互斥量和事件
来源:互联网 发布:软件需求分析模板 编辑:程序博客网 时间:2024/05/16 05:02
互斥量是系统内核对象,谁拥有就谁执行。它与临界区工作很类似。
不同处在于:
1、互斥量可以跨进程边界同步线程。
2、可以给互斥量取个名字,通过引用互斥量的名字来使用一个已知的互斥量对象。
使用互斥量之类的对象需要反复调用系统内核,期间需要进行进程上下文转换和控制级别转换,大概需要耗费400到600个时间周期。
又是图书馆的比喻,现在是搞一个锁,把钥匙(互斥量句柄)交给管理员(操作系统),每一个人(线程)想要借书的时候,都要向管理员拿钥匙。当有人在使用的时候,另一人必须等待,等到钥匙有空的时候(互斥量进入信号状态),才能拿到钥匙(拥有了句柄)办理借书业务(此时互斥量进入非信号状态直到办完业务)。
使用互斥量的步骤:
1、声明一个全局的互斥量句柄变量(var hMutex: THandle;);
2、创建互斥量:CreateMutex(
lpMutexAttributes: PSecurityAttributes;
bInitialOwner: BOOL;
lpName: PWideChar ): THandle;
(lpMutexAttributes参数:指向TSecurityAttributes的指针,安全属性,一般用缺省安全属性nil;
bInitialOwer参数:表示创建的互斥量线程是否是互斥量的属主,如果该参数为False互斥量就没属主,一般来讲应设为False,否则如果设为True的话,要当主线程结束其他线程才成为它的属主才能运行;
lpName参数:是互斥量的名字,若打算取名的话,则传入nil。)
3、用等待函数控制线程进入同步代码块:WaitForSingleObject(
hHandle:THandel;
dwMilliseconds:DWORD):DWORD;
(hHandel参数:是对象的句柄,不同对象信号状态不同,对于互斥量而言当没有线程占有时,互斥量就时入信号状态;
dwMilliseconds参数:可以是一个时间段,可以是0表示仅检查对象状态后立即返回,可以是INFINITE值表示函数一直等待直到对象进入信号状态;
返回值常量如下:WAIT_ABANDONED指定的对象是互斥量对象,拥有这个互斥量对象的线程在没有释放互斥量之前就已经终止,称作废弃互斥量,此时该互斥量归调用线程所拥有,并把这个互斥量设为非信号状态;WAIT_OBJECT_0指定对象的进入信号状态;WAIT_TIMEOUT等待时间已过,对象状态依然是无信号状态)
4、执行线程运行代码。
5、线程运行完后释放互斥量的拥有权:ReleaseMutex(hMutex: THandle);
主Form调用:
源代码下载:ThreadDemo.rar
不同处在于:
1、互斥量可以跨进程边界同步线程。
2、可以给互斥量取个名字,通过引用互斥量的名字来使用一个已知的互斥量对象。
使用互斥量之类的对象需要反复调用系统内核,期间需要进行进程上下文转换和控制级别转换,大概需要耗费400到600个时间周期。
又是图书馆的比喻,现在是搞一个锁,把钥匙(互斥量句柄)交给管理员(操作系统),每一个人(线程)想要借书的时候,都要向管理员拿钥匙。当有人在使用的时候,另一人必须等待,等到钥匙有空的时候(互斥量进入信号状态),才能拿到钥匙(拥有了句柄)办理借书业务(此时互斥量进入非信号状态直到办完业务)。
使用互斥量的步骤:
1、声明一个全局的互斥量句柄变量(var hMutex: THandle;);
2、创建互斥量:CreateMutex(
lpMutexAttributes: PSecurityAttributes;
bInitialOwner: BOOL;
lpName: PWideChar ): THandle;
(lpMutexAttributes参数:指向TSecurityAttributes的指针,安全属性,一般用缺省安全属性nil;
bInitialOwer参数:表示创建的互斥量线程是否是互斥量的属主,如果该参数为False互斥量就没属主,一般来讲应设为False,否则如果设为True的话,要当主线程结束其他线程才成为它的属主才能运行;
lpName参数:是互斥量的名字,若打算取名的话,则传入nil。)
3、用等待函数控制线程进入同步代码块:WaitForSingleObject(
hHandle:THandel;
dwMilliseconds:DWORD):DWORD;
(hHandel参数:是对象的句柄,不同对象信号状态不同,对于互斥量而言当没有线程占有时,互斥量就时入信号状态;
dwMilliseconds参数:可以是一个时间段,可以是0表示仅检查对象状态后立即返回,可以是INFINITE值表示函数一直等待直到对象进入信号状态;
返回值常量如下:WAIT_ABANDONED指定的对象是互斥量对象,拥有这个互斥量对象的线程在没有释放互斥量之前就已经终止,称作废弃互斥量,此时该互斥量归调用线程所拥有,并把这个互斥量设为非信号状态;WAIT_OBJECT_0指定对象的进入信号状态;WAIT_TIMEOUT等待时间已过,对象状态依然是无信号状态)
4、执行线程运行代码。
5、线程运行完后释放互斥量的拥有权:ReleaseMutex(hMutex: THandle);
6、最后关闭互斥量:CloseHandle(hMutex: THandle);
自定义线程:
{线程类}unit CustomThread;interfaceuses Classes,StdCtrls,SysUtils,Windows;type TEventThread = class(TThread) private FLabel:TLabel; str:String; procedure Show; protected procedure Execute; override; public Constructor Create(aLabel:TLabel); end; TMutexThread = class(TThread) private FLabel:TLabel; str:String; procedure Show; protected procedure Execute; override; public Constructor Create(aLabel:TLabel); end;implementationuses DemoMain;{ TEventThread }constructor TEventThread.Create(aLabel: TLabel);begin FLabel:=aLabel; Inherited Create(False);end;procedure TEventThread.Execute;var i:Integer;begin FreeOnTerminate:=True; for i := 0 to 2000 do begin Sleep(5); if WaitForSingleObject(hEvent,INFINITE)=WAIT_OBJECT_0 then begin if not Terminated then begin str:=Format('线程ID:%.4d,第%.4d个循环。',[GetCurrentThreadId,i]); Synchronize(Show); // 线程调用vcl控件,必须要用Synchronize,否则会出错 end; end; end;end;procedure TEventThread.Show;begin FLabel.Caption:=str;end;{ TMutexThread }procedure TMutexThread.Show;begin FLabel.Caption:=str;end;Constructor TMutexThread.Create(aLabel: TLabel);begin FLabel:=aLabel; Inherited Create(False);end;procedure TMutexThread.Execute;var i:Integer;begin// if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then// begin// try// for i := 0 to 2000 do// Sleep(5);// begin// if not Terminated then// begin// str:=Format('线程ID:%.4d,第%.2d个循环。',[GetCurrentThreadId,i]);// Synchronize(Show);// end;// end;// finally// ReleaseMutex(hMutex);// end;// end; for i := 0 to 2000 do begin Sleep(5); if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then begin try if not Terminated then begin str:=Format('线程ID:%.4d,第%.2d个循环。',[GetCurrentThreadId,i]); Synchronize(Show); end; finally ReleaseMutex(hMutex); end; end; end;end;end.
主Form调用:
type TWorkMode = (wmEvent, wmMutex); TFormMain = class(TForm) Panel1: TPanel; GroupBox1: TGroupBox; Panel2: TPanel; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; btnPulseEvent: TButton; btnResetEvent: TButton; btnSetEvent: TButton; Button1: TButton; GroupBox2: TGroupBox; Button2: TButton; procedure Button1Click(Sender: TObject); procedure btnSetEventClick(Sender: TObject); procedure btnPulseEventClick(Sender: TObject); procedure btnResetEventClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var FormMain: TFormMain; hEvent:THandle; hMutex:THandle;implementation{$R *.dfm}uses CustomThread;procedure TFormMain.btnPulseEventClick(Sender: TObject);begin PulseEvent(hEvent); //PulseEvent(执行一次后立即暂停)end;procedure TFormMain.btnResetEventClick(Sender: TObject);begin ResetEvent(hEvent); // ResetEvent(暂停运行)end;procedure TFormMain.btnSetEventClick(Sender: TObject);begin SetEvent(hEvent); //SetEvent(启动运行)end;procedure TFormMain.Button1Click(Sender: TObject);begin TEventThread.Create(Label1); TEventThread.Create(Label2); TEventThread.Create(Label3); TEventThread.Create(Label4); TEventThread.Create(Label5);end;procedure TFormMain.Button2Click(Sender: TObject);begin TMutexThread.Create(Label1); TMutexThread.Create(Label2); TMutexThread.Create(Label3); TMutexThread.Create(Label4); TMutexThread.Create(Label5);end;procedure TFormMain.FormCreate(Sender: TObject);begin{ lpEventAttributes参数,指向TSecurityAttributes记录的指针,一般可以缺省填入nil值; bManualReset参数,是否可手动暂停,True为可手动,False为事件对象控制一次后将立即暂停; bInitialState参数,初始状态,True为事件对象创建后处可运行状态,False为暂停状态; lpName参数,事件的名称; 返回值为句柄。} hEvent:=CreateEvent(nil,True,True,nil); hMutex:=CreateMutex(nil,false,'MyThreadDemo');end;procedure TFormMain.FormDestroy(Sender: TObject);begin CloseHandle(hEvent); CloseHandle(hMutex);end;
源代码下载:ThreadDemo.rar
- Delphi Thread互斥量和事件
- Delphi Thread 进程和线程函数(1)
- delphi中的事件和消息
- [delphi]如何为Delphi程序添加事件和事件处理器
- VC线程Thread和事件Event
- delphi 事件和属性的绑定
- Delphi Thread 线程2
- Delphi Thread 线程同步
- Delphi Thread(3)
- Delphi Thread(3)
- Delphi 事件
- 如何为Delphi程序添加事件和事件处理器
- 如何为Delphi程序添加事件和事件处理器
- 如何为Delphi程序添加事件和事件处理器
- Delphi Thread 线程(1)
- Delphi中的线程类Thread
- Events (Delphi)Delphi中事件
- delphi的属性property和消息处理特点事件属性。
- 雅思作文实用技巧之连接词
- 输入AAABBBBCCDDD,统计A B C D各多少(结果是A3B4C2D3)
- FTP常见反馈信息知识大全
- IPS +IDS 来保证你服务器的安全
- mvc的认识
- Delphi Thread互斥量和事件
- 服务里面找不到MYSQL的解决方法
- 题目1126: 还是A+B
- eclipse failed to create the java virtual machine 问题图文解析
- 数字转成汉字表示(如222,1221 ,注意特殊情况:101,1001,10100等)
- Fuse用户空间文件系统安装学习笔记(ver2.7.3 red hat)
- 文献阅读
- JSF,第二代Java页面技术
- 收藏的网页-DotNet