TThread的Synchronize(Method: TThreadMethod)方法可以将method交由主线程执行,避免多线程冲突,但这样等于没有使用多线程性能。
能不能提供线程三种同步方式的示例,多谢啦。
能不能提供线程三种同步方式的示例,多谢啦。
解决方案 »
- 如何在保存dbgrid里记录前,断幵数据源连接,保存成功后再连接。
- 看见很多单机应用程序使用类似web的界面,很清晰明朗,这种界面可否用DELPHI实现?怎么才能实现? (在线等)
- 关于一个工程中单元数太多的解决方案
- 很急的哦,菜鸟问题!
- 如何关闭CreateOleObject('internetExplorer.Application')打开的IE窗口
- MDI子窗口切换!
- 那位仁兄能帮助我解决这个问题的?
- 请教这样的SQL语句如何写?很简单的!!!
- 用什么制作帮助文件
- query的sql中使用order by 之后变为只读,如何添加数据?
- 我用delph5.0编写的三层结构的程序里,不能实现调用有参数的函数
- 为什么我用BDE方式连接数据库,每次都要用户名和密码?
最简单的方法就是用操作系统提供的同步机制正如洪峰鸟所说,这几个东西很简单帮助里有很好的例子,你可以在帮助里查找我这里没有装Delphi也没有Msdn所以没法给你查。
你就查semaphore就可以了
用的是互斥
unit Main;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TMainForm = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
procedure ThreadsDone(Sender: TObject);
end; TFooThread = class(TThread)
protected
procedure Execute; override;
end;var
MainForm: TMainForm;implementation{$R *.DFM}const
MaxSize = 128;var
NextNumber: Integer = 0;
DoneFlags: Integer = 0;
GlobalArray: array[1..MaxSize] of Integer;
hMutex: THandle = 0;function GetNextNumber: Integer;
begin
Result := NextNumber; // return global var
Inc(NextNumber); // inc global var
end;procedure TFooThread.Execute;
var
i: Integer;
begin
FreeOnTerminate := True;
OnTerminate := MainForm.ThreadsDone;
if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
begin
for i := 1 to MaxSize do
begin
GlobalArray[i] := GetNextNumber; // set array element
Sleep(5); // let thread intertwine
end;
end;
ReleaseMutex(hMutex);
end;procedure TMainForm.ThreadsDone(Sender: TObject);
var
i: Integer;
begin
Inc(DoneFlags);
if DoneFlags = 2 then // make sure both threads finished
begin
for i := 1 to MaxSize do
{ fill listbox with array contents }
Listbox1.Items.Add(IntToStr(GlobalArray[i]));
CloseHandle(hMutex);
end;
end;procedure TMainForm.Button1Click(Sender: TObject);
begin
hMutex := CreateMutex(nil, False, nil);
TFooThread.Create(False); // create threads
TFooThread.Create(False);
end;
end.
TDoorThread=class(TThread)
private
Current:smallint;
InterTimes:Integer; //线程轮询间隔
ThreadMode:byte; //线程模式,1-人工,2-自动,3-计划
ThreadActed:boolean; //标示线程是否工作
Successed:boolean; //标示当前门控器数据采集是否成功
procedure GatherDoorData; //采集刷卡记录
procedure CheckAuthor; //检测UserAuthor表中是否有记录,有则导入Periods表并下载
procedure DownLoadPeriods(address:smallint);
procedure DecodeSetting(OldSetting:string);
public
procedure execute;override;
end;TCommandThread=class(TThread)
private
Current:smallint;
InterTimes:Integer; //线程轮询间隔
ThreadActed:boolean; //标示线程是否工作
procedure DoCommand; //执行WEB命令,操作门控器
public
procedure execute;override;
end;以下是执行过程定义
procedure TCommandThread.execute ;
beginif planed then begin
Current:=0;
while current<Times do begin
DoCommand;
Inc(Current);
end;
end
elsewhile true do begin
try
Sleep(1000*InterTimes);
DoCommand;
if not ThreadActed then exit;
except
continue;
end;
end; //while
end;procedure TDoorthread.execute ;
begin
case ThreadMode of
1:
begin
GatherDoorData;
CheckAuthor;
end;
2:
while true do begin
Sleep(1000*InterTimes);
GatherDoorData;
CheckAuthor;
if not ThreadActed then exit;
end; //while
3:
begin
Current:=0;
while current<Times do begin
GatherDoorData;
CheckAuthor;
Inc(Current);
end; //while
end;end;//caseend;我在这两个线程的execute过程中使用死循环不断执行一些过程,这些过程访问了相同的全局变量,全局变量多为pchar,在这两个线程创建之前已经分配内存。程序不够稳定,有死机现象。如何解决。
rwdx(任我独行) ,请问你有没有API线程函数的demo,我在MSDN中只有函数说明,没有demo.
哦,对了,semaphore是什么工具,我这里没有。
线程访问全局对象/变量,或者是引用关系的对象时,需要同步的支持,不然的话会经常出现“地址访问错:oxfffffdfdsf",什么什么的一般我们线程访问全局对象/变量/引用的对象,最简单的用Synchrize(ProcMethod),
其它的还有:
SyncObjs.TSimpleEvent, TEvent类
CreateEvent //建立一个事件,安全,是否自动设置为无信号(waitFor完成后),初始信号,名称
WaitFor //如果设置为自动无信号,waitFor会将Event设为无信号
SetEvent //设置有信号
ResetEvent //设置无信号CreateSemaphore //建立信号,安全(nil),初始,最大引用计数器,名称
WaitFor //waitfor使Semaphore--,即说Semaphore的资源--,如超过最大计数器则阻塞进程
ReleaseSemaphore //将Semaphore++CreateMutex //互斥信号,
WaitFor //将信号lock,不成功则阻塞进程
ReleaseMutex //工作做完了,将信号UnLock,别的线程才能waitforWaitFor ==> WaitForSingleObject, WaitForMutpleObjects, Msg....还有TCriticalSection就比较简单了,不说了
具体方面具体使用了,看它适合哪方面。
最后记住CloseHandle(Event/Semaphore/Mutex);你说的Semaphore就是CreateSemaphore之类的。
application.ProcessMessages();
访问数据前:TCriticalSection.enter,访问完毕后用TCriticalSection.leave祝你好运
type
TDoorThread=class(TThread)
private
Current:smallint;
InterTimes:Integer; //线程轮询间隔
ThreadMode:byte; //线程模式,1-人工,2-自动,3-计划
ThreadActed:boolean; //标示线程是否工作
Successed:boolean; //标示当前门控器数据采集是否成功
procedure GatherDoorData; //采集刷卡记录
procedure CheckAuthor; //检测UserAuthor表中是否有记录,有则导入Periods表并下载
procedure DownLoadPeriods(address:smallint);
procedure DecodeSetting(OldSetting:string);
public
procedure execute;override;
end;
var
iCriticalSection:TCriticalSetion;procedure Tform1.create(Sender: TObject);
begin
iCriticalSection:=TCriticalSetion.create;
end;procedure TDoorthread.execute ;
begin
iCriticalSection.enter; //加上这句case ThreadMode of
1:
begin
GatherDoorData;
CheckAuthor;
end;
2:
while true do begin
Sleep(1000*InterTimes);
GatherDoorData;
CheckAuthor;
if not ThreadActed then exit;
end; //while
3:
begin
Current:=0;
while current<Times do begin
GatherDoorData;
CheckAuthor;
Inc(Current);
end; //while
end;end;//case
iCriticalSection.leave;//加上这句end;其他的线程execute方法中也写上上述两句iCriticalSection.enter和TCriticalSection.leave?这样写能解决问题吗?