1.首先,你的信号量,定义有问题。 信号量应该是一个全局变量,或你的多个线程的局部变量,而不应该是单个线程的私有变量,这样多个线程才可以通过它来同步,否则同步是不起作用的。
type
TMyThread = class(TThread)
private
FParentHandle: THandle;
FSemaphore: THandle;
type
TMyThread = class(TThread)
private
FParentHandle: THandle;
FSemaphore: THandle;
解决方案 »
- 我用IDHTTP的get和post接收到的数据怎么解码啊。。
- DELPH程序界面,能否做成像讯雷一样的,而且可以随便调整上下左右的宽度。
- 求教启动画面中启动状态的显示(如3DMAX等)
- 怎样修改OEM信息?
- 短信编程
- 保存图片到数据库的问题
- JAVA高手请回答,Jave图片特技功能能加入到Delphi exe里吗?
- 怎么样拦截mask edit的出错信息,加入自己的信息啊
- delphi 自动编号 access数据库
- Delpi如何存取SQLSERVER的Image或者binary字段。
- 数据库的别名问题?
- serversocket1.Socket.LocalAddress;得到0.0.0.0?????
小子对这多线程总是有点糊涂,所以根据那VCL的一个类写了个Demo,它也是这么定义的。
那个类好像是启用线程来发送数据。如果信号量要全局变量,那把它定义到TForm1中,再传到线程也可。
不如你跟我讲讲信号在线程中的作用吧。
请继续。
多线程同步,通常用的最多的是,多个功能相同的工作线程之间的同步。多个功能相同的工作线程在一起,通常又叫线程池.他们要完成特定的随机产生的多个任务。单个的任务通常映射为一个消息,多个任务映射的多个消息通常称为消息池。
我说觉得在那个线程中用不用Semaphore是一样的。原来是为了多线程中同步访问消息资源而弄的。
那个信号好像只有CreateSemaphore是只允许一个线程来访问,如果是多个需要的话,那在线程中建立就没什么意义了。不错。
每个线程中必须要ReleaseSemaphore将这信号置为signaled,表示已经有线程使用了这个,那怎么当线程完成后,再把它置为noSignaled.用什么函数。
这信号的API好像只有CreateSemaphore,OpenSemaphore,ReleaseSemaphore,
是用OpenSemaphore吧,打开一个存在的Semaphore对象。它会不会将信号置noSignled,
还有如果ReleaseSemaphore不成功,它是等待,还是怎么样
接下来是MsgWaitForMultipleObject返回值。
那个Wait_Object_0值它什么时候才会返回。
还有Time_Out.各位虾们,不是我不想给分,只是俺是初级用户,只能给这些分。
ReleaseSemaphore,是信号量加一。不成功会返回错误码的吧。
我看了下help,它说用ReleaseSemaphore将信号占用后,用信号句柄用Wait function调用返回后将会置为noSignled,但是我没有用它的句柄作为参数进行调用啊。所以Wait function不会置noSignled,怪了,那它该什么置了,用什么来置了?
FMyThread := Create ===> Execute(ReleaseSemaphore, MsgWaitForSingleObject) ==>
线程结束后,WaitForSingleObject将置信号为noSigned(可以同时启动另个进程,不过由Semaphore控制着)
呵呵,多谢宝兄
继续 MsgWaitForMultipleObject
干哈,干哈呀?
收分呗
顺便,up提高收视率!
顺便,up提高收视率!
顺便,up提高收视率!
发错了,不好意思。 没有工具(delphi,msdn,网吧),下次再说吧?
var
Msg: TMsg;
begin
ReleaseSemaphore(FSemaphore, 1, nil);
while not Terminated do
case MsgWaitForMultipleObjects(1, Msg, False, ThreadTimeOut, QS_ALLINPUT) of
WAIT_OBJECT_0: //这个Case什么时候触发啊。
PostMessage(FParentHandle, WM_MyMessage, Msg.wParam, Integer(Pointer(PChar('I don''t not mean'))));
//如果有消息,将把从消息队列中全部取出并删除,看是否自己定义的消息,不然交由VCL自带的处理方式处理。
WAIT_OBJECT_0 + 1: //取出并删除
while PeekMessage(Msg, 0, WM_USER, WM_MyMessage, PM_REMOVE) do
if Msg.hwnd = 0 then
if Msg.message = WM_MyMessage then
PostMessage(FParentHandle, WM_MyMessage, Msg.wParam, Msg.lParam)
else DispatchMessage(Msg)
else DispatchMessage(Msg);
WAIT_TIMEOUT: //为什么不触发TimeOut,在哪设,是不是说上面的WaitFor执行的期间,如果没有消息,它是挂起的啊
begin
Terminate;
PostMessage(FParentHandle, WM_MyMessage, Msg.wParam, Integer(Pointer(PChar('Time Out'))));
end;
end;
end;
DWORD nCount, // number of handles in the handle array
LPHANDLE pHandles, // pointer to the object-handle array
BOOL fWaitAll, // wait for all or wait for one
DWORD dwMilliseconds, // time-out interval in milliseconds
DWORD dwWakeMask // type of input events to wait for
); pHandles:通常是指向信号量,不知道木兄,为何要指向,一个消息。//线程中除了Wait_Object_0 + 1会执行外,其它的都case 不了。
也就是这个问题。
多个工作线程,为了协调完成多个任务。必将同步有序的访问他们的消息池。
这个消息池,一般都是自定义的消息队列。用wondows消息干扰太多。
Waitfor函数一般也用WaitForMultipleObjects,WaitForSingleObject
TMyThread = class(TThread)
private
FParentHandle: THandle;
FSemaphore: THandle;
FEvent: TSimpleEvent; //增加一个控制事件对象。
protected
procedure Execute; override;
public //由调用线程传来。
constructor Create(ParentHandle: THandle; Event: TSimpleEvent);
destructor Destroy; override;
property Semaphore: THandle read FSemaphore;
end;procedure TMyThread.Execute;
var
Msg: TMsg;
Event: THandle;
begin
...
Event := FEvent.Handle;
...
MsgWaitForMutipleObjects(1, Event, False, ThreadTimeOut, QS_ALLINPUT) of
...
end;
//OK
FEvent是由主调用线程创建的一个Mutux事件,另外还有一个线程也是调用了这个Mutex事件句柄。它可能会触发这个Mutext事件。那么在这个线程中的MsgWaitForMutipleObjects就会返回Wait_Object_0这个值了。终于明白了。
如果大家有兴趣,可以看TSocketConnection,还有它关联的TSocketTransport,TTransportThread类,它们是相互工作的。
这个Demo就是根据它写的,不过那个MsgWaitForMutipleObjects写的.....哈哈。
所以,在此非常多谢 airhorse(编程至尊宝)
114分等会送上。让大家看看。