使用 "goto" 停止 C/freeRTOS 中的任务
Using "goto" to stop a task in C/freeRTOS
我正在使用状态机任务来处理我的程序流。 When a state is selected (other than STAND BY), the State Machine wake up the associated task with the “xTaskNotifyGive” function as all other tasks are locked by “ulTaskNotifyTake( pdTRUE, portMAX_DELAY);”
在执行那些与状态相关的任务期间,可能会发生问题,与状态相关的任务必须停止。为了做到这一点,安全任务设置了一个标志“ContinueTask”。在状态相关的任务中,我们定期检查这个标志。如果为false,后面的代码将不会执行。
目前,代码结构如下所示:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
...
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
问题是,如果我们第一次检查时设置了标志,它仍然会在下一部分代码中检查它。
解决这个问题的方法是使用级联的 if/else 语句,如下所示:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//code
}
else{
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//code
}
else{
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//code
}
else{
....
}
}
}
但是如果我们在任务中多次检查这个标志,缩进的数量会非常多,并且无法阅读。
我想知道,在这种情况下,是否可以使用“goto”语句,如下所示:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally) goto exitTask;
//some code
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally) goto exitTask;
//some code
...
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally) goto exitTask;
//some code
exitTask:
//code before exiting task
你怎么看?我对这些 "goto" 声明进行了一些研究,但我无法确定是否可以使用,因为有些人不同意这个问题,但没有给出额外的理由。
对我来说,这是使用 short circuit boolean logic 的好情况。
即:如果标志曾经设置为 false
,&&
表达式的第二部分将不会被计算。函数 ContinueTaskCopy()
不会是 运行.
只要flag是true
,所有代码都会运行.
一旦标志为 false
,它将跳过所有 if 语句和所有 ContinueTaskCopy
语句,直到函数结束。
使您的代码看起来像:
bool ContinueTaskInterally = true;
ContinueTaskInternally = ContinueTaskInterally && ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
ContinueTaskInternally = ContinueTaskInterally && ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
...
ContinueTaskInternally = ContinueTaskInterally && ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
在不对 "goto" 关键字的用法给出我的意见的情况下,我认为您可以使用以下代码实现相同的行为并避免圈复杂度:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally)
{
//some code
//...
ContinueTaskInternally = ContinueTaskCopy();
}
if (ContinueTaskInternally)
{
//some code
//...
ContinueTaskInternally = ContinueTaskCopy();
}
if (ContinueTaskInternally)
{
//some code
//...
}
//code before exiting task
是的。 goto
不推荐,但在你的情况下,它会起作用。我只想在这里解释一下为什么 goto
不推荐:
1.动态内存分配
如果您动态分配内存(malloc
通常,GlobalAlloc
在 Windows 等),您可以执行如下代码:
int* something = (int*)malloc(sizeof(int));
// do something
if (condition) goto endProgram;
free(something);
endProgram:
// "something" may haven't been freed
因此 something
将保持分配状态。
2。了解未定义行为的代码和风险
goto
会使您的代码可读性降低或非常不直接。让我们看看这个例子:
if (condition) goto someLabel;
if (anotherCondition) {
someLabel:
// code
goto abc;
}
for (int i = 0; i < limit; ++i) {
// some code
abc:
// other code
}
所以我们跳到第二个if
如果condition
为真...那么我们跳到for
的中间...有些代码可能还没有执行包括将 i
设置为 0,因此它是未定义的行为......可以在没有 goto
.
的情况下重新考虑此代码
在这种特定情况下,我认为 goto 非常适合。这样你就得到了最清晰有效的解决方案。就像其他所有事情一样,请确保您了解您正在使用的工具以避免弄得一团糟。而且很容易造成混乱和误用 "goto".
我正在使用状态机任务来处理我的程序流。 When a state is selected (other than STAND BY), the State Machine wake up the associated task with the “xTaskNotifyGive” function as all other tasks are locked by “ulTaskNotifyTake( pdTRUE, portMAX_DELAY);”
在执行那些与状态相关的任务期间,可能会发生问题,与状态相关的任务必须停止。为了做到这一点,安全任务设置了一个标志“ContinueTask”。在状态相关的任务中,我们定期检查这个标志。如果为false,后面的代码将不会执行。
目前,代码结构如下所示:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
...
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
问题是,如果我们第一次检查时设置了标志,它仍然会在下一部分代码中检查它。
解决这个问题的方法是使用级联的 if/else 语句,如下所示:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//code
}
else{
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//code
}
else{
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally){
//code
}
else{
....
}
}
}
但是如果我们在任务中多次检查这个标志,缩进的数量会非常多,并且无法阅读。
我想知道,在这种情况下,是否可以使用“goto”语句,如下所示:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally) goto exitTask;
//some code
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally) goto exitTask;
//some code
...
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally) goto exitTask;
//some code
exitTask:
//code before exiting task
你怎么看?我对这些 "goto" 声明进行了一些研究,但我无法确定是否可以使用,因为有些人不同意这个问题,但没有给出额外的理由。
对我来说,这是使用 short circuit boolean logic 的好情况。
即:如果标志曾经设置为 false
,&&
表达式的第二部分将不会被计算。函数 ContinueTaskCopy()
不会是 运行.
只要flag是true
,所有代码都会运行.
一旦标志为 false
,它将跳过所有 if 语句和所有 ContinueTaskCopy
语句,直到函数结束。
使您的代码看起来像:
bool ContinueTaskInterally = true;
ContinueTaskInternally = ContinueTaskInterally && ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
ContinueTaskInternally = ContinueTaskInterally && ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
...
ContinueTaskInternally = ContinueTaskInterally && ContinueTaskCopy();
if (ContinueTaskInternally){
//some code
}
在不对 "goto" 关键字的用法给出我的意见的情况下,我认为您可以使用以下代码实现相同的行为并避免圈复杂度:
ContinueTaskInternally = ContinueTaskCopy();
if (ContinueTaskInternally)
{
//some code
//...
ContinueTaskInternally = ContinueTaskCopy();
}
if (ContinueTaskInternally)
{
//some code
//...
ContinueTaskInternally = ContinueTaskCopy();
}
if (ContinueTaskInternally)
{
//some code
//...
}
//code before exiting task
是的。 goto
不推荐,但在你的情况下,它会起作用。我只想在这里解释一下为什么 goto
不推荐:
1.动态内存分配
如果您动态分配内存(malloc
通常,GlobalAlloc
在 Windows 等),您可以执行如下代码:
int* something = (int*)malloc(sizeof(int));
// do something
if (condition) goto endProgram;
free(something);
endProgram:
// "something" may haven't been freed
因此 something
将保持分配状态。
2。了解未定义行为的代码和风险
goto
会使您的代码可读性降低或非常不直接。让我们看看这个例子:
if (condition) goto someLabel;
if (anotherCondition) {
someLabel:
// code
goto abc;
}
for (int i = 0; i < limit; ++i) {
// some code
abc:
// other code
}
所以我们跳到第二个if
如果condition
为真...那么我们跳到for
的中间...有些代码可能还没有执行包括将 i
设置为 0,因此它是未定义的行为......可以在没有 goto
.
在这种特定情况下,我认为 goto 非常适合。这样你就得到了最清晰有效的解决方案。就像其他所有事情一样,请确保您了解您正在使用的工具以避免弄得一团糟。而且很容易造成混乱和误用 "goto".