如何在不同的函数中使用互斥锁和解锁。

huangapple go评论79阅读模式
英文:

How to use mutex lock and unluck in different functions

问题

以下是您要翻译的内容:

我有多个函数按顺序执行。
第一个函数确定RAM中的位置指针,如果该位置与另一个线程共享,则调用互斥锁的锁定函数。
第二个函数处理指针指向的数据,然后解锁资源。一旦程序执行mtx.lock(),它就会停止执行,程序不再继续。我在模拟CPU和简单的图形芯片,试图锁定被两者访问的内存位置(CPU和“GPU”运行在不同的线程上)。我试图防止上述两个线程同时访问内存中的位置。
我为虚拟内存(数组)中的每个地址或地址范围都有一个互斥锁。目前只有“CPU”线程锁定互斥锁,还未实现“GPU”线程,因此当“CPU”第一次执行锁定函数时,它们不能被锁定。
更具体地说,“CPU”在单独的线程上运行,“GPU”与显示输出一起在主线程上运行。如果这是错误的地方,我没有调用thread_cpu.join()(其中thread_cpu像这样初始化:std::thread thread_cpu(cpu.run());)。
我的代码如下所示:
sync.h(在多个cpp文件中包含)

inline std::mutex mtx;

memory.cpp(返回指针并锁定互斥锁,在指针处理后,通过post_process解锁互斥锁)

#include "sync.h"

class Memory{
private:
     UInt32* virtual_memory;

public:
     Memory(){
          virtual_memory = new UInt32[0x2000];
     };

     UInt32* get_address(UInt32 addr_virt){
          mtx.lock();
          return &virtual_memory[addr_virt];
     }

     void post_process(){
          mtx.unlock();
     }
}

实际上更复杂,但这展示了互斥锁的实现。如何实现这种功能?

英文:

I have multiple functions that get executed in a row.
The first function determines a pointer to a location in ram and in case the location is shared with another thread it calls the lock function of mutex.
The second function processes the data pointed to by the pointer and afterwards I unlock the ressource. As soon as the programm executes mtx.lock() it gets stuck so the programm just stops proceeding. I'm emulating a cpu and a simple graphicschip and I try to lock memory locations which get accessed by both (THe cpu and "gpu" run on different threads). I am trying to prevent simultaneous access to the locations in memory which are accessed by both threads mentioned above.
I have a mutex for each of those addresses or address ranges in the virtual memory(array). Currently only the "cpu" thread locks the mutex, they are not implemented yet for the gpu, so they can't be locked when the "cpu" executes the lock function the first time.

More precisely, the "cpu" runs on a seperate thread and the "gpu" with display output runs on the main thread. I don't call thread_cpu.join(), in case this is the error (where thread_cpu is initialized like std::thread thread_cpu(cpu.run());).

My code looks like this:

sync.h (included in multiple cpp files)

inline std::mutex mtx;

memory.cpp (returns the pointer and locks the mutex, after the processing with the pointer the mutex gets unlocked by post_process)

#include "sync.h"

class Memory{
private:
     UInt32* virtual_memory;

public:
     Memory(){
          virtual_memory = new UInt32[0x2000];
     };

     UInt32* get_address(UInt32 addr_virt){
          mtx.lock();
          return &virtual_memory[addr_virt];
     }

     void post_process(){
          mtx.unlock();
     }
}

In reality it's more complex but this shows how the mutex is implemented. how could one achieve this functionality?

答案1

得分: 1

我强烈建议从一个简单的、通用的规则开始:不要直接锁定或解锁互斥量。

相反,建议使用类似于 std::lock_guard(或者根据情况可能是 std::scoped_lockstd::unique_lock)的方式锁定互斥量,该方式会在离开锁定范围时自动解锁互斥量。

例如:

     UInt32* get_address(UInt32 addr_virt){
          std::lock_guard L(mtx);
          return &virtual_memory[addr_virt];
     }

如果需要调用多个期望互斥量在整个过程中一直保持拥有的函数,请创建一个锁定互斥量的函数,然后按规定的顺序调用这些函数:

void foo() { 
    std::lock_guard L(mtx);
    a(); // a()、b() 和 c() 都不处理互斥量。
    b();
    c();
}

不,你不能在一个线程中锁定互斥量,然后在另一个线程中执行相应的解锁。当一个线程锁定互斥量时,同一个线程需要解锁互斥量。互斥量的整个目的是确保在锁定互斥量时只有一个线程可以访问共享资源。如果一个线程锁定了互斥量,而另一个线程解锁了它,那就会背离互斥量的整个目的。

英文:

I'd (strongly) advise starting with a simple, general rule: don't directly lock or unlock a mutex.

Instead, make it a practice to lock the mutex with something like std::lock_guard (or std::scoped_lock or std::unique_lock depending on the situation) that unlocks the mutex automatically when leaving the scope in which you locked it.

For example:

     UInt32* get_address(UInt32 addr_virt){
          std::lock_guard L(mtx);
          return &virtual_memory[addr_virt];
     }

If you need to call multiple functions that expect the mutex to be owned throughout, create a function that locks the mutex, and then calls the functions in the prescribed order:

void foo() { 
    std::lock_guard L(mtx);
    a(); // none of a(), b() or c() deals with the mutex at all.
    b();
    c();
}

And no, you can't lock a mutex in one thread, then do the matching unlock from another thread. When one thread locks a mutex, that same thread needs to unlock the mutex. The whole point of a mutex is to ensure that only one thread can access the shared resource while the mutex is locked. If one thread locked the mutex, and another unlocked it, that would subvert the whole purpose of having a mutex to start with.

huangapple
  • 本文由 发表于 2023年5月14日 01:19:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定