Fal*_*lko 5 c++ multithreading mutex locking esp32
我正在尝试锁定 ESP32。显然,有不同的方法来实现锁:
有默认的 C++ 互斥体库:
#include <mutex>
std::mutex mtx;
mtx.lock();
mtx.unlock();
Run Code Online (Sandbox Code Playgroud)RTOS 的实现如下:
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();
xSemaphoreTake(xMutex, portMAX_DELAY);
xSemaphoreGive(xMutex);
Run Code Online (Sandbox Code Playgroud)我应该注意哪些根本区别吗?或者说它们是等价的?
假设您使用ESP-IDF SDK,该工具链基于针对 xtensa-lx106 指令集的 GCC 5.2,并具有部分开源的 C 运行时库。
std::mutex在 GNU libstdc++ 中委托 pthread_mutex_lock/unlock 调用。ESP-IDF SDK 包含一个pthread 模拟层,我们可以在其中查看实际执行的pthread_mutex_lock操作pthread_mutex_unlock:
static int IRAM_ATTR pthread_mutex_lock_internal(esp_pthread_mutex_t *mux, TickType_t tmo)
{
if (!mux) {
return EINVAL;
}
if ((mux->type == PTHREAD_MUTEX_ERRORCHECK) &&
(xSemaphoreGetMutexHolder(mux->sem) == xTaskGetCurrentTaskHandle())) {
return EDEADLK;
}
if (mux->type == PTHREAD_MUTEX_RECURSIVE) {
if (xSemaphoreTakeRecursive(mux->sem, tmo) != pdTRUE) {
return EBUSY;
}
} else {
if (xSemaphoreTake(mux->sem, tmo) != pdTRUE) {
return EBUSY;
}
}
return 0;
}
int IRAM_ATTR pthread_mutex_unlock(pthread_mutex_t *mutex)
{
esp_pthread_mutex_t *mux;
if (!mutex) {
return EINVAL;
}
mux = (esp_pthread_mutex_t *)*mutex;
if (!mux) {
return EINVAL;
}
if (((mux->type == PTHREAD_MUTEX_RECURSIVE) ||
(mux->type == PTHREAD_MUTEX_ERRORCHECK)) &&
(xSemaphoreGetMutexHolder(mux->sem) != xTaskGetCurrentTaskHandle())) {
return EPERM;
}
int ret;
if (mux->type == PTHREAD_MUTEX_RECURSIVE) {
ret = xSemaphoreGiveRecursive(mux->sem);
} else {
ret = xSemaphoreGive(mux->sem);
}
if (ret != pdTRUE) {
assert(false && "Failed to unlock mutex!");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它主要将调用委托给 RTOS 信号量 API,并进行一些额外的检查。
您很可能不需要/不想要这些支票。考虑到 esp32 芯片的微小 i-cache 和极其缓慢的串行 RAM,我宁愿尽可能靠近硬件(即,除非它完全满足std::mutex您的需要,否则不要使用)。