如上所述,here使用volatile std::string
并不是一个好主意。
我正在FreeRTOS上开发应用程序,我需要在任务之间移动一个字符串。有一个任务通过UART
接收命令,其他任务可以要求该任务以获取对指定命令的响应。我想在字符串上使用std::move
以使应用程序最佳。
是否可以方便快捷地替换volatile std::string
,还是我必须自己实现一个带有volatile
字段的类?也许这种方法不好,我应该使用另一种结构来处理命令响应的变化?
编辑:这是一些代码。
我通过中断获得命令的单个字节。这些命令是以\r
结尾的可读命令。
void rx_interrupt(char c)
{
if(c == '\r')
{
c == '\0')
BaseType_t higher_prior_task_woken = pdFALSE;
vTaskNotifyGiveFromISR(rx_task_handle, &higher_prior_task_woken);
portYIELD_FROM_ISR(higher_prior_task_woken);
}
rx_buf.push_byte(c);
}
rx_buf
是一个循环缓冲区,它允许将整个命令弹出为std::string
。
然后rx_task
:
for (;;)
{
auto notif_num = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
while (notif_num--)
{
auto comm = rx_buf.pop_command();
if (comm.length() == 0)
continue;
if (is_unsolicited_command(comm))
handle_unsolicited_command(std::move(comm));
if (is_awaited_command(comm))
handle_awaited_command(std::move(comm));
}
}
rx_task
是必需的,因为我必须首先检查是否发生了由未经请求的命令指示的异步事件。
收到的(等待的)命令可能很长,所以我想移动它们。
void handle_awaited_command(std::string &&cmd)
{
os_lockguard guard(var_mux);
if (!awaiting)
return;
awaited_command = std::move(cmd); // Problematic line
xSemaphoreGive(cmd_received_sem);
awaited_cmd_handled = true;
}
最后,其他任何任务都可以等待命令:
std::string get_command()
{
os_lockguard guard_glob(mux);
{
os_lockguard guard(var_mux);
awaiting = true;
}
xSemaphoreTake(cmd_received_sem, timeout);
{
os_lockguard guard(var_mux);
if(awaited_cmd_handled)
return std::move(awaited_command); // Problematic line
else
return std::string("");
}
}
问题在于定义看起来像这样:
volatile bool awaiting;
volatile bool awaited_cmd_handled;
volatile std::string awaited_command;
所以我这里有一个volatile std::string
。