繁体   English   中英

为什么TMutex方法Acquire()无法锁定互斥锁?

[英]Why does TMutex method Acquire() not lock a mutex?

到目前为止,我有以下代码:

****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();
}

问题是, mtx->Acquire()不会锁定互斥锁,当我注释mtx->Release()时,运行时没有任何变化,两个线程可以同时访问相同的共享资源,这不是我想要的想。 我在Linux环境中使用p_threads,并且互斥锁被锁定时,其他线程正在等待它变为可用。 如何使用C ++ CodeGear 2009达到相同的结果?

因为TMutex::Acquire确实确实获得了互斥对象的锁,所以可以用其他方式解释您的问题。 TMutex的实现如下所示:

procedure TMutex.Acquire;
begin
  if WaitFor(INFINITE) = wrError then
    RaiseLastOSError;
end;

procedure TMutex.Release;
begin
  if not ReleaseMutex(FHandle) then
    RaiseLastOSError;
end;

然后WaitFor调用WaitForMultipleObjectsEx传递互斥锁句柄。

最有可能的是,您实际上以某种方式拥有多个互斥体,但是由于我看不到您的所有代码,因此我无法确定。

最后,在进程同步中,您应该首选Windows关键部分,该部分的性能优于Windows互斥对象。 这就是RTL中的TCriticalSection


更新之后,很容易看到发生了什么。 所有对锁的使用都发生在主线程中。 您调用Synchronize ,这将导致该方法在主线程上执行。 如果直接从Execute方法中调用CheckLock ,则将按预期方式死锁。

您需要对所有GUI调用使用“ Synchronize ”。 从广义上讲,它通过向主线程发信号通知同步队列中有内容,然后等待主线程完成工作来起作用。 它是一种异步方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM