unit threadUnit;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Gauges;type TForm1 = class(TForm) CreateThread: TButton; procedure CreateThreadClick(Sender: TObject); private ThreadHandle : THandle; ThreadHandle1 : THandle; ThreadHandle2 : THandle; MutexHandle: THandle; { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}function ThreadFunc0(Info: Pointer): Integer; stdcall var ICount: Integer; // general loop counter CountStr: string; // holds a string representation of the counter begin {wait for the mutex to become signaled. the mutex is created signaled so this thread gets ownership of the mutex and starts immediatly} WaitForSingleObject(Form1.MutexHandle, INFINITE); {start a counter to display something} for ICount := 1 to 10000 do begin CountStr := IntToStr(ICount); Form1.Canvas.TextOut(10, 10, 'Thread 1 '+CountStr); end; {Release ownership of the mutex so the other threads can fire} ReleaseMutex(Form1.MutexHandle); ExitThread(1); end;function ThreadFunc1(Info: Pointer): Integer; stdcall var ICount: Integer; // general loop counter CountStr: string; // holds a string representation of the counter begin {wait for the mutex to become signaled. the mutex is created signaled so this thread gets ownership of the mutex and starts immediatly} WaitForSingleObject(Form1.MutexHandle, INFINITE); {start a counter to display something} for ICount := 1 to 10000 do begin CountStr := IntToStr(ICount); Form1.Canvas.TextOut(110, 10, 'Thread 2 '+CountStr); end; {Release ownership of the mutex so the other threads can fire} ReleaseMutex(Form1.MutexHandle); ExitThread(2); end;function ThreadFunc2(Info: Pointer): Integer; stdcall var ICount: Integer; // general loop counter CountStr: string; // holds a string representation of the counter LocalMutexHandle: THandle; // holds a handle to the mutex begin {open a Handle to the mutex from this thread} LocalMutexHandle := OpenMutex(MUTEX_ALL_ACCESS, FALSE, 'MyMutex'); {take ownership of the mutex. this will wait until the mutex is signaled} WaitForSingleObject(LocalMutexHandle, INFINITE); {start a counter to display something} for ICount := 1 to 10000 do begin CountStr := IntToStr(ICount); Form1.canvas.TextOut(210, 10, 'Thread 3 '+CountStr); end; {Release ownership of the mutex} ReleaseMutex(LocalMutexHandle); {close the mutex handle} CloseHandle(LocalMutexHandle); ExitThread(3); end;procedure TForm1.CreateThreadClick(Sender: TObject); var ThreadId0, ThreadId1, ThreadId2: DWORD; // holds thread identifiers begin {Create the mutex with the name MyMutex. the mutex is signaled so the first thread will start imediatly} MutexHandle := CreateMutex(nil, False, 'MyMutex'); {Create the first thread, and start it immediatly} ThreadHandle := Windows.CreateThread(nil, 0, @ThreadFunc0, nil, 0, ThreadId0); {Create the second thread, and start it immediatly} ThreadHandle1 := Windows.CreateThread(nil,0, @ThreadFunc1, nil, 0, ThreadId1); {Create the third thread, and start it immediatly} ThreadHandle2 := Windows.CreateThread(nil,0, @ThreadFunc2, nil, 0, ThreadId2); {Stop the main thread for a short time so that the other threads get a chance to take ownership of the mutex before the main thread calls WaitForSingleObject} Sleep(1000); {Take ownership of the mutex; this will wait until the mutex is signaled} WaitForSingleObject(MutexHandle, INFINITE); {Close the mutexHandle so that this will work agian} CloseHandle(MutexHandle); end;end.
但是如果有其中一个线程正在使用MUTEX的时候非正常中止,会不会自动释放掉MuteX?
五星,CSDN工作为员?在Project文件是加上这个函数 如: program iTVS;uses Forms, Windows, Main in 'Main.pas' {MainForm}, Criteria in 'Criteria.pas' {CriteriaDlg}, Acctrpt in 'AcctRpt.pas' {StatementOfAccountForm}, Archrpt in 'ArchRpt.pas' {ArchiveForm}, Company in 'Company.pas' {CompanyDlg}, Comprpt in 'comprpt.pas' {CompanyReport}, conndlg in 'conndlg.pas' {ConnectDlg}, About in 'About.pas' {AboutDlg}, Folder in 'folder.pas' {FolderDlg}, Frmpopup in 'frmpopup.pas' {PopupForm}, Holidet in 'Holidet.pas' {HolidayDlg}, Inbox in 'Inbox.pas' {InboxForm}, Inboxrpt in 'Inboxrpt.pas' {InboxReport}, Docseq in 'Docseq.pas' {DocSeqDlg}, LstMemo in 'lstmemo.pas' {ListMemoForm}, Lkpath in 'lkpath.pas' {LookuppathDlg}, Login in 'Login.pas' {LoginDlg}, Outbox in 'outbox.pas' {OutboxForm}, Partner in 'Partner.pas' {PartnerDlg}, Partrpt in 'partrpt.pas' {PartnerReport}, Password in 'Password.pas' {PasswordDlg}, Newsdet in 'newsdet.pas' {NewsDetDlg}, Sentrpt in 'sentRpt.pas' {SentReport}, Prodrpt in 'prodrpt.pas' {ProductReport}, Product in 'Product.pas' {ProductDlg}, Sentbox in 'sentbox.pas' {SentboxForm}, Syspar in 'SysPar.pas' {SysParDlg}, Support in 'Support.pas' {SupportForm}, Syslgrpt in 'SysLgRpt.pas' {SystemLogReport}, Syslog in 'Syslog.pas' {SysLogForm}, Viewstat in 'ViewStat.pas' {ViewStatForm}, Upgrade in 'upgrade.pas' {UpgradeDlg}, User in 'User.pas' {UserDlg}, Userdet in 'userdet.pas' {UserDetDlg}, Userrpt in 'Userrpt.pas' {UserReport}, Viewarch in 'ViewArch.pas' {ViewArchForm}, Import in 'Import.pas' {ImffInterface}, CKey in 'CKey.pas' {CKey_Form}, CKeyRpt in 'CKeyRpt.pas' {CKeyRptForm}, AKey in 'AKey.pas' {AKey_Form}, AKeyRpt in 'AKeyRpt.pas' {AKeyRptForm}, Inboxdlg in 'Inboxdlg.pas' {InboxPrintDlg};{$R *.RES}begin CreateMutex(nil, FALSE, 'iTVS'); if GetLastError = ERROR_ALREADY_EXISTS then Halt(0); Application.Initialize; Application.Title := 'ValuNet Standard on Internet'; Application.HelpFile := 'ValuHelp.hlp'; Application.CreateForm(TMainForm, MainForm); Application.Run;end.
var H:THandle; Res:TResourceStream; Rslt:Integer; SysDir,OCXName:String; begin H:=CreateMutex(nil,False,'I am the only one!'); if H<>0 then if GetLastError=ERROR_ALREADY_EXISTS then begin CloseHandle(H); Exit; end; end;
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Gauges;type
TForm1 = class(TForm)
CreateThread: TButton;
procedure CreateThreadClick(Sender: TObject);
private
ThreadHandle : THandle;
ThreadHandle1 : THandle;
ThreadHandle2 : THandle;
MutexHandle: THandle;
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}function ThreadFunc0(Info: Pointer): Integer; stdcall
var
ICount: Integer; // general loop counter
CountStr: string; // holds a string representation of the counter
begin
{wait for the mutex to become signaled. the mutex is created signaled so
this thread gets ownership of the mutex and starts immediatly}
WaitForSingleObject(Form1.MutexHandle, INFINITE); {start a counter to display something}
for ICount := 1 to 10000 do
begin
CountStr := IntToStr(ICount);
Form1.Canvas.TextOut(10, 10, 'Thread 1 '+CountStr);
end; {Release ownership of the mutex so the other threads can fire}
ReleaseMutex(Form1.MutexHandle);
ExitThread(1);
end;function ThreadFunc1(Info: Pointer): Integer; stdcall
var
ICount: Integer; // general loop counter
CountStr: string; // holds a string representation of the counter
begin
{wait for the mutex to become signaled. the mutex is created signaled so
this thread gets ownership of the mutex and starts immediatly}
WaitForSingleObject(Form1.MutexHandle, INFINITE); {start a counter to display something}
for ICount := 1 to 10000 do
begin
CountStr := IntToStr(ICount);
Form1.Canvas.TextOut(110, 10, 'Thread 2 '+CountStr);
end; {Release ownership of the mutex so the other threads can fire}
ReleaseMutex(Form1.MutexHandle);
ExitThread(2);
end;function ThreadFunc2(Info: Pointer): Integer; stdcall
var
ICount: Integer; // general loop counter
CountStr: string; // holds a string representation of the counter
LocalMutexHandle: THandle; // holds a handle to the mutex
begin
{open a Handle to the mutex from this thread}
LocalMutexHandle := OpenMutex(MUTEX_ALL_ACCESS, FALSE, 'MyMutex'); {take ownership of the mutex. this will wait until the mutex is signaled}
WaitForSingleObject(LocalMutexHandle, INFINITE); {start a counter to display something}
for ICount := 1 to 10000 do
begin
CountStr := IntToStr(ICount);
Form1.canvas.TextOut(210, 10, 'Thread 3 '+CountStr);
end; {Release ownership of the mutex}
ReleaseMutex(LocalMutexHandle); {close the mutex handle}
CloseHandle(LocalMutexHandle);
ExitThread(3);
end;procedure TForm1.CreateThreadClick(Sender: TObject);
var
ThreadId0, ThreadId1, ThreadId2: DWORD; // holds thread identifiers
begin
{Create the mutex with the name MyMutex. the mutex is signaled
so the first thread will start imediatly}
MutexHandle := CreateMutex(nil, False, 'MyMutex'); {Create the first thread, and start it immediatly}
ThreadHandle := Windows.CreateThread(nil, 0, @ThreadFunc0, nil, 0, ThreadId0); {Create the second thread, and start it immediatly}
ThreadHandle1 := Windows.CreateThread(nil,0, @ThreadFunc1, nil, 0, ThreadId1); {Create the third thread, and start it immediatly}
ThreadHandle2 := Windows.CreateThread(nil,0, @ThreadFunc2, nil, 0, ThreadId2); {Stop the main thread for a short time so that the other threads get
a chance to take ownership of the mutex before the main thread
calls WaitForSingleObject}
Sleep(1000); {Take ownership of the mutex; this will wait until the mutex is signaled}
WaitForSingleObject(MutexHandle, INFINITE); {Close the mutexHandle so that this will work agian}
CloseHandle(MutexHandle);
end;end.
如:
program iTVS;uses
Forms,
Windows,
Main in 'Main.pas' {MainForm},
Criteria in 'Criteria.pas' {CriteriaDlg},
Acctrpt in 'AcctRpt.pas' {StatementOfAccountForm},
Archrpt in 'ArchRpt.pas' {ArchiveForm},
Company in 'Company.pas' {CompanyDlg},
Comprpt in 'comprpt.pas' {CompanyReport},
conndlg in 'conndlg.pas' {ConnectDlg},
About in 'About.pas' {AboutDlg},
Folder in 'folder.pas' {FolderDlg},
Frmpopup in 'frmpopup.pas' {PopupForm},
Holidet in 'Holidet.pas' {HolidayDlg},
Inbox in 'Inbox.pas' {InboxForm},
Inboxrpt in 'Inboxrpt.pas' {InboxReport},
Docseq in 'Docseq.pas' {DocSeqDlg},
LstMemo in 'lstmemo.pas' {ListMemoForm},
Lkpath in 'lkpath.pas' {LookuppathDlg},
Login in 'Login.pas' {LoginDlg},
Outbox in 'outbox.pas' {OutboxForm},
Partner in 'Partner.pas' {PartnerDlg},
Partrpt in 'partrpt.pas' {PartnerReport},
Password in 'Password.pas' {PasswordDlg},
Newsdet in 'newsdet.pas' {NewsDetDlg},
Sentrpt in 'sentRpt.pas' {SentReport},
Prodrpt in 'prodrpt.pas' {ProductReport},
Product in 'Product.pas' {ProductDlg},
Sentbox in 'sentbox.pas' {SentboxForm},
Syspar in 'SysPar.pas' {SysParDlg},
Support in 'Support.pas' {SupportForm},
Syslgrpt in 'SysLgRpt.pas' {SystemLogReport},
Syslog in 'Syslog.pas' {SysLogForm},
Viewstat in 'ViewStat.pas' {ViewStatForm},
Upgrade in 'upgrade.pas' {UpgradeDlg},
User in 'User.pas' {UserDlg},
Userdet in 'userdet.pas' {UserDetDlg},
Userrpt in 'Userrpt.pas' {UserReport},
Viewarch in 'ViewArch.pas' {ViewArchForm},
Import in 'Import.pas' {ImffInterface},
CKey in 'CKey.pas' {CKey_Form},
CKeyRpt in 'CKeyRpt.pas' {CKeyRptForm},
AKey in 'AKey.pas' {AKey_Form},
AKeyRpt in 'AKeyRpt.pas' {AKeyRptForm},
Inboxdlg in 'Inboxdlg.pas' {InboxPrintDlg};{$R *.RES}begin
CreateMutex(nil, FALSE, 'iTVS');
if GetLastError = ERROR_ALREADY_EXISTS then
Halt(0);
Application.Initialize;
Application.Title := 'ValuNet Standard on Internet';
Application.HelpFile := 'ValuHelp.hlp';
Application.CreateForm(TMainForm, MainForm);
Application.Run;end.
如果有其中一个线程正在使用MUTEX的时候非正常中止,会不会自动释放掉MuteX?
CreateMutex(nil, FALSE, 'iTVS');是如果有其中一个线程正在使用MUTEX的时候非正常中止,不会自动释放掉MuteX,但你可以通过 ReleaseMutex来释放掉MuteX
如果所有需要使用MUTEX的线程都用无限时来等待,不是要永远也没结果么?如果用限时等待我又不知道应该设成多长时间合适。
比如出现上面的情况,我设5秒等待时间,如果超出5秒,我是不是应该直接调用ReleaseMutex来释放掉Mutex?
但此时可能那个线程并未终止,而花的时间偶然间因为某些原因延长了,如果线程正在使用Mutex,而Mutex被其它线程释放掉,又会出现什么意外情况?请 Wally_wu(韦利) 帮帮忙啊
如果是多个线程:使用API函数WaitForMultipleObjects
H:THandle;
Res:TResourceStream;
Rslt:Integer;
SysDir,OCXName:String;
begin H:=CreateMutex(nil,False,'I am the only one!');
if H<>0 then
if GetLastError=ERROR_ALREADY_EXISTS then
begin
CloseHandle(H);
Exit;
end;
end;