为什么第三个线程不执行? ( 积分: 30 )

  • 主题发起人 主题发起人 awfigsk
  • 开始时间 开始时间
A

awfigsk

Unregistered / Unconfirmed
GUEST, unregistred user!
unit threadUnit;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> &nbsp;StdCtrls, Gauges;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;CreateThread: TButton;<br> &nbsp; &nbsp;procedure CreateThreadClick(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;ThreadHandle : THandle;<br> &nbsp; &nbsp;ThreadHandle1 : THandle;<br> &nbsp; &nbsp;ThreadHandle2 : THandle;<br> &nbsp; &nbsp;MutexHandle: THandle;<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>function ThreadFunc0(Info: Pointer): Integer; stdcall<br>var<br> &nbsp;ICount: Integer; &nbsp; &nbsp; &nbsp; &nbsp;// general loop counter<br> &nbsp;CountStr: string; &nbsp; &nbsp; &nbsp; // holds a string representation of the counter<br>begin<br> &nbsp;WaitForSingleObject(Form1.MutexHandle, INFINITE);<br><br> &nbsp;for ICount := 1 to 10000 do<br> &nbsp;begin<br> &nbsp; &nbsp;CountStr := IntToStr(ICount);<br> &nbsp; &nbsp;Form1.Canvas.TextOut(10, 10, 'Thread 1 '+CountStr);<br> &nbsp;end;<br><br> &nbsp;ReleaseMutex(Form1.MutexHandle);<br> &nbsp;ExitThread(1);<br>end;<br><br>function ThreadFunc1(Info: Pointer): Integer; stdcall<br>var<br> &nbsp;ICount: Integer; &nbsp; &nbsp; &nbsp; &nbsp;// general loop counter<br> &nbsp;CountStr: string; &nbsp; &nbsp; &nbsp; // holds a string representation of the counter<br>begin<br> &nbsp;WaitForSingleObject(Form1.MutexHandle, INFINITE);<br> &nbsp;for ICount := 1 to 10000 do<br> &nbsp;begin<br> &nbsp; &nbsp;CountStr := IntToStr(ICount);<br> &nbsp; &nbsp;Form1.Canvas.TextOut(110, 10, 'Thread 2 '+CountStr);<br> &nbsp;end;<br><br> &nbsp;ReleaseMutex(Form1.MutexHandle);<br> &nbsp;ExitThread(2);<br>end;<br><br>function ThreadFunc2(Info: Pointer): Integer; stdcall<br>var<br> &nbsp;ICount: Integer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // general loop counter<br> &nbsp;CountStr: string; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// holds a string representation of the counter<br> &nbsp;LocalMutexHandle: THandle; // holds a handle to the mutex<br>begin<br> &nbsp;LocalMutexHandle := OpenMutex(MUTEX_ALL_ACCESS, FALSE, 'MyMutex');<br><br> &nbsp;WaitForSingleObject(LocalMutexHandle, INFINITE);<br><br> &nbsp;for ICount := 1 to 10000 do<br> &nbsp;begin<br> &nbsp; &nbsp;CountStr := IntToStr(ICount);<br> &nbsp; &nbsp;Form1.canvas.TextOut(210, 10, 'Thread 3 '+CountStr);<br> &nbsp;end;<br><br> &nbsp;ReleaseMutex(LocalMutexHandle);<br><br> &nbsp;CloseHandle(LocalMutexHandle);<br> &nbsp;ExitThread(3);<br>end;<br><br>procedure TForm1.CreateThreadClick(Sender: TObject);<br>var<br> &nbsp;ThreadId0, ThreadId1, ThreadId2: DWORD; // holds thread identifiers<br>begin<br> &nbsp;MutexHandle := CreateMutex(nil, False,'MyMutex');<br><br> &nbsp;ThreadHandle := Windows.CreateThread(nil, 0, @ThreadFunc0, nil, 0, ThreadId0);<br><br> &nbsp;ThreadHandle1 := Windows.CreateThread(nil,0, @ThreadFunc1, nil, 0, ThreadId1);<br><br> &nbsp;ThreadHandle2 := Windows.CreateThread(nil,0, @ThreadFunc2, nil, 0, ThreadId2);<br><br> &nbsp;Sleep(1000);<br><br> &nbsp;WaitForSingleObject(MutexHandle, INFINITE);<br><br> &nbsp;CloseHandle(MutexHandle);<br>end;<br><br>上面这段代码执行后,线程3好像不会执行,但是我如果将线程3的建立语句ThreadHandle2=....放到ThreadHandle或Threadhandle1前面,则处理第三个位置的Thread建立语句好像都不会执行,并且我将Sleep的值设大也不会执行。<br>但当我在ThreadFunc2中最前面加入一个showmessage()语句来进行调试时,Thread3又可以执行,去掉这条语句就不会执行。这个问题是出在哪?<br>还请高手大侠们指点,谢谢!
 
unit threadUnit;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> &nbsp;StdCtrls, Gauges;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;CreateThread: TButton;<br> &nbsp; &nbsp;procedure CreateThreadClick(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;ThreadHandle : THandle;<br> &nbsp; &nbsp;ThreadHandle1 : THandle;<br> &nbsp; &nbsp;ThreadHandle2 : THandle;<br> &nbsp; &nbsp;MutexHandle: THandle;<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>function ThreadFunc0(Info: Pointer): Integer; stdcall<br>var<br> &nbsp;ICount: Integer; &nbsp; &nbsp; &nbsp; &nbsp;// general loop counter<br> &nbsp;CountStr: string; &nbsp; &nbsp; &nbsp; // holds a string representation of the counter<br>begin<br> &nbsp;WaitForSingleObject(Form1.MutexHandle, INFINITE);<br><br> &nbsp;for ICount := 1 to 10000 do<br> &nbsp;begin<br> &nbsp; &nbsp;CountStr := IntToStr(ICount);<br> &nbsp; &nbsp;Form1.Canvas.TextOut(10, 10, 'Thread 1 '+CountStr);<br> &nbsp;end;<br><br> &nbsp;ReleaseMutex(Form1.MutexHandle);<br> &nbsp;ExitThread(1);<br>end;<br><br>function ThreadFunc1(Info: Pointer): Integer; stdcall<br>var<br> &nbsp;ICount: Integer; &nbsp; &nbsp; &nbsp; &nbsp;// general loop counter<br> &nbsp;CountStr: string; &nbsp; &nbsp; &nbsp; // holds a string representation of the counter<br>begin<br> &nbsp;WaitForSingleObject(Form1.MutexHandle, INFINITE);<br> &nbsp;for ICount := 1 to 10000 do<br> &nbsp;begin<br> &nbsp; &nbsp;CountStr := IntToStr(ICount);<br> &nbsp; &nbsp;Form1.Canvas.TextOut(110, 10, 'Thread 2 '+CountStr);<br> &nbsp;end;<br><br> &nbsp;ReleaseMutex(Form1.MutexHandle);<br> &nbsp;ExitThread(2);<br>end;<br><br>function ThreadFunc2(Info: Pointer): Integer; stdcall<br>var<br> &nbsp;ICount: Integer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // general loop counter<br> &nbsp;CountStr: string; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// holds a string representation of the counter<br> &nbsp;LocalMutexHandle: THandle; // holds a handle to the mutex<br>begin<br> &nbsp;LocalMutexHandle := OpenMutex(MUTEX_ALL_ACCESS, FALSE, 'MyMutex');<br><br> &nbsp;WaitForSingleObject(LocalMutexHandle, INFINITE);<br><br> &nbsp;for ICount := 1 to 10000 do<br> &nbsp;begin<br> &nbsp; &nbsp;CountStr := IntToStr(ICount);<br> &nbsp; &nbsp;Form1.canvas.TextOut(210, 10, 'Thread 3 '+CountStr);<br> &nbsp;end;<br><br> &nbsp;ReleaseMutex(LocalMutexHandle);<br><br> &nbsp;CloseHandle(LocalMutexHandle);<br> &nbsp;ExitThread(3);<br>end;<br><br>procedure TForm1.CreateThreadClick(Sender: TObject);<br>var<br> &nbsp;ThreadId0, ThreadId1, ThreadId2: DWORD; // holds thread identifiers<br>begin<br> &nbsp;MutexHandle := CreateMutex(nil, False,'MyMutex');<br><br> &nbsp;ThreadHandle := Windows.CreateThread(nil, 0, @ThreadFunc0, nil, 0, ThreadId0);<br><br> &nbsp;ThreadHandle1 := Windows.CreateThread(nil,0, @ThreadFunc1, nil, 0, ThreadId1);<br><br> &nbsp;ThreadHandle2 := Windows.CreateThread(nil,0, @ThreadFunc2, nil, 0, ThreadId2);<br><br> &nbsp;Sleep(1000);<br><br> &nbsp;WaitForSingleObject(MutexHandle, INFINITE);<br><br> &nbsp;CloseHandle(MutexHandle);<br>end;<br><br>上面这段代码执行后,线程3好像不会执行,但是我如果将线程3的建立语句ThreadHandle2=....放到ThreadHandle或Threadhandle1前面,则处理第三个位置的Thread建立语句好像都不会执行,并且我将Sleep的值设大也不会执行。<br>但当我在ThreadFunc2中最前面加入一个showmessage()语句来进行调试时,Thread3又可以执行,去掉这条语句就不会执行。这个问题是出在哪?<br>还请高手大侠们指点,谢谢!
 
单独建立一个线程单位,然后引用公共的执行事件就可以了。
 
主要是为什么第三个线程执行不了?<br>我将CreateThread按钮的Click事件改成如下,并且将线程中循环的值加大,设为100000,这时有时可以三个线程的TextOut都显示出来,但有时只能显示第一和第三个线程,第二个线程反而不执行,并且有时第三个线程的值不会到达100000,而是小于100000的值,就不执行了。<br>在下面的第一个Textout有时会将'主线程'显示出来,很少可以三个Textout都显示出来,有时一个TextOut都不会显示出来。<br><br>procedure TForm1.CreateThreadClick(Sender: TObject);<br>var<br> &nbsp;ThreadId0, ThreadId1, ThreadId2: DWORD; // holds thread identifiers<br>begin<br> &nbsp;MutexHandle := CreateMutex(nil, False,'MyMutex');<br> &nbsp;ThreadHandle := Windows.CreateThread(nil, 0, @ThreadFunc0, nil, 0, ThreadId0);<br> &nbsp;ThreadHandle1 := Windows.CreateThread(nil,0, @ThreadFunc1, nil, 0, ThreadId1);<br> &nbsp;ThreadHandle2 := Windows.CreateThread(nil,0, @ThreadFunc2, nil, 0, ThreadId2);<br> &nbsp;Sleep(5000);<br><br> &nbsp;Form1.Canvas.TextOut(10,30,'主线程');<br><br> &nbsp;Form1.Canvas.TextOut(10,60,'主线程WaitForSingleObject');<br> &nbsp;CloseHandle(MutexHandle);<br> &nbsp;Form1.Canvas.TextOut(10,80,'主线程CloseHandle');<br>end;<br><br>上面这个程序的执行原理是怎么样的呢?很是糊涂!
 
是因为建立第三个线程的语句的下面代码不管是<br>Sleep(1000)<br>还是<br>WaitForSingleObject(MutexHandle, INFINITE);<br>都会使主线程阻塞,也就是说这时它不会处理任何消息,包括刷新界面,但你的第三个<br>个线程此时又正在更新界面,由于主线程已经被阻塞,所以线程三会在等待,主线程也会<br>在等待,这就是线程三看起来不会被执行的原因。<br>------------------------------------------------------------------------------<br>自由界面和报表的完美解决方案<br>http://www.anylib.com
 
不管是哪个子线程,只要主线程进入阻塞,那么子线程(可能正在执行到半或还没执行)都会被挂起,这也能解释你把循环加大出现的状况。
 
Sleep(1000);<br>WaitForSingleObject(MutexHandle, INFINITE);<br>CloseHandle(MutexHandle);<br><br>去掉就可以了,
 
后退
顶部