gpt4 book ai didi

c++ - 为什么 TMutex 方法 Acquire() 不锁定互斥量?

转载 作者:太空宇宙 更新时间:2023-11-04 14:20:56 27 4
gpt4 key购买 nike

到目前为止我有这段代码:

****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。从广义上讲,它的工作原理是向主线程发出同步队列中有内容的信号,然后等待主线程完成工作。它是一种异步方法。

关于c++ - 为什么 TMutex 方法 Acquire() 不锁定互斥量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7753436/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com