[英]Why does TMutex method Acquire() not lock a mutex?
So far I have this code: 到目前为止,我有以下代码:
****SimpleForm.h****
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
TMutex *mtx;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
****SimpleForm.cpp****
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
mtx = new TMutex(true);
WorkerThread *wt = new WorkerThread(false, mtx);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
mtx->Acquire();
Memo1->Lines->Add("Locked...");
mtx->Release();
}
****WorkerThread.h****
class WorkerThread : public TThread
{
private:
TMutex *mtx;
protected:
void __fastcall Execute();
public:
__fastcall WorkerThread(bool CreateSuspended, TMutex *mtx);
void __fastcall CheckLock();
};
****WorkerThread.cpp****
__fastcall WorkerThread::WorkerThread(bool CreateSuspended, TMutex *mtx)
: TThread(CreateSuspended)
{
this->mtx = mtx;
}
void __fastcall WorkerThread::Execute()
{
while(true){
Sleep(1000);
Synchronize(CheckLock);
}
}
void __fastcall WorkerThread::CheckLock(){
this->mtx->Acquire();
Form1->Memo1->Lines->Add("Locked from thread");
//this->mtx->Release();
}
The problem is, mtx->Acquire()
does not lock a mutex, when I comment the mtx->Release()
, nothing changes during runtime, both threads can access the same shared resource at the same time, witch is not what I want. 问题是, mtx->Acquire()
不会锁定互斥锁,当我注释mtx->Release()
时,运行时没有任何变化,两个线程可以同时访问相同的共享资源,这不是我想要的想。 I was using p_threads in Linux environment, and when the mutex is locked, other threads waits for it to become available. 我在Linux环境中使用p_threads,并且互斥锁被锁定时,其他线程正在等待它变为可用。 How can I achieve the same result using C++ CodeGear 2009 ? 如何使用C ++ CodeGear 2009达到相同的结果?
Something else is the explanation to your problem because TMutex::Acquire
does indeed acquire a lock on the mutex object. 因为TMutex::Acquire
确实确实获得了互斥对象的锁,所以可以用其他方式解释您的问题。 The implementation of TMutex
looks like this: TMutex
的实现如下所示:
procedure TMutex.Acquire;
begin
if WaitFor(INFINITE) = wrError then
RaiseLastOSError;
end;
procedure TMutex.Release;
begin
if not ReleaseMutex(FHandle) then
RaiseLastOSError;
end;
And WaitFor
calls WaitForMultipleObjectsEx
passing the mutex handle. 然后WaitFor
调用WaitForMultipleObjectsEx
传递互斥锁句柄。
Most likely is that you actually have more than one mutex somehow but I can't tell for sure since I can't see all of your code. 最有可能的是,您实际上以某种方式拥有多个互斥体,但是由于我看不到您的所有代码,因此我无法确定。
Finally, for within process synchronisation you should prefer the Windows critical section which performs better than the Windows mutex object. 最后,在进程同步中,您应该首选Windows关键部分,该部分的性能优于Windows互斥对象。 That is TCriticalSection
in the RTL. 这就是RTL中的TCriticalSection
。
Following your update it is easy to see what is happening. 更新之后,很容易看到发生了什么。 All use of the lock happens in the main thread. 所有对锁的使用都发生在主线程中。 You call Synchronize
which results in the method executing on the main thread. 您调用Synchronize
,这将导致该方法在主线程上执行。 If you call CheckLock
directly from your Execute
method then you will deadlock as intended. 如果直接从Execute
方法中调用CheckLock
,则将按预期方式死锁。
You need to use Synchronize
for all GUI calls. 您需要对所有GUI调用使用“ Synchronize
”。 It works, broadly, by signaling the main thread that there is something in the synchronize queue and then waiting until the main thread has completed the work. 从广义上讲,它通过向主线程发信号通知同步队列中有内容,然后等待主线程完成工作来起作用。 It is an asynchronous method. 它是一种异步方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.