生活随笔
收集整理的這篇文章主要介紹了
多任务的死锁问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 多任務的死鎖問題
- 1.1 死鎖示例
- 1.2 死鎖的概念
- 1.3 應對死鎖
1 多任務的死鎖問題
1.1 死鎖示例
代碼如下:
#include "tinyOS.h"
#include "app.h"
#include "hal.h"static tTask task1
;
static tTask task2
;
static tTask task3
;
static tTask task4
; static tTaskStack task1Env
[TASK1_ENV_SIZE
];
static tTaskStack task2Env
[TASK2_ENV_SIZE
];
static tTaskStack task3Env
[TASK3_ENV_SIZE
];
static tTaskStack task4Env
[TASK4_ENV_SIZE
]; int task1Flag
;
int task2Flag
;
int task3Flag
;
int task4Flag
; static tMutex mutexA
;
static tMutex mutexB
;
void task1Entry
(void *param
) {for (;;) {tMutexWait(&mutexA
, 0);interruptByOtherTask(); tMutexWait(&mutexB
, 0);task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1);tMutexNotify(&mutexB
);tMutexNotify(&mutexA
); task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1); }
}
void task2Entry
(void *param
) {for (;;) {tMutexWait(&mutexB
, 0);interruptByOtherTask(); tMutexWait(&mutexA
, 0);task2Flag
= 1;tTaskDelay(1);task2Flag
= 0;tTaskDelay(1);tMutexNotify(&mutexA
);tMutexNotify(&mutexB
);task2Flag
= 1;tTaskDelay(1);task2Flag
= 0;tTaskDelay(1);}
}
void task3Entry
(void *param
) {for (;;) {task3Flag
= 1;tTaskDelay(1);task3Flag
= 0;tTaskDelay(1);}
}
void task4Entry
(void *param
) {for (;;) {task4Flag
= 1;tTaskDelay(1);task4Flag
= 0;tTaskDelay(1);}
}
void tInitApp
(void) {halInit();tMutexInit(&mutexA
);tMutexInit(&mutexB
);tTaskInit(&task1
, task1Entry
, (void *) 0x0, TASK1_PRIO
, task1Env
, sizeof(task1Env
));tTaskInit(&task2
, task2Entry
, (void *) 0x0, TASK2_PRIO
, task2Env
, sizeof(task2Env
));tTaskInit(&task3
, task3Entry
, (void *) 0x0, TASK3_PRIO
, task3Env
, sizeof(task3Env
));tTaskInit(&task4
, task4Entry
, (void *) 0x0, TASK4_PRIO
, task4Env
, sizeof(task4Env
));
}
1.2 死鎖的概念
兩個或兩個以上的任務在執行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。
死鎖產生條件:
以上幾個條件,其中互斥、非剝奪一般是我們所用RTOS默認支持,其余條件則由實際應用、程序員編寫方式決定。
1.3 應對死鎖
預防死鎖:
為了避免死鎖產生影響整個系統的運行,有三種方式:
- 預防:破壞產生的幾個條件,容易直觀。
- 避免:分配資源前檢查,如發生死鎖則不分配,避免死鎖。
- 檢測和恢復:按一定的策略檢測是否有死鎖,然后恢復。
以上幾種方式,對我們所用的RTOS而言,一般只能做到預防。而具體的預防措施,其原理在于打破死鎖產生的幾個條件。根據前面的死鎖條件,我們只能對控制"請求保持"、“循環等待” 這兩個條件施加影響。
具體解決:
- 一性全部分配資源,盡可能避免請求和等待。借助等待資源的超時機制,中間雖有可能發生死鎖,但由于超時釋放了已申請的資源,避免了超時等待。
#include "tinyOS.h"
#include "app.h"
#include "hal.h"static tTask task1
;
static tTask task2
;
static tTask task3
;
static tTask task4
; static tTaskStack task1Env
[TASK1_ENV_SIZE
];
static tTaskStack task2Env
[TASK2_ENV_SIZE
];
static tTaskStack task3Env
[TASK3_ENV_SIZE
];
static tTaskStack task4Env
[TASK4_ENV_SIZE
]; int task1Flag
;
int task2Flag
;
int task3Flag
;
int task4Flag
; static tMutex mutexA
;
static tMutex mutexB
;
void task1Entry
(void *param
) {for (;;) {do {int error
= 0;tMutexWait(&mutexA
, 0);interruptByOtherTask(); error
= tMutexWait(&mutexB
, 10);if (error
== tErrorNoError
) {break;}tMutexNotify(&mutexA
); } while (1);task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1);tMutexNotify(&mutexB
);tMutexNotify(&mutexA
); task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1); }
}
void task2Entry
(void *param
) {for (;;) {tMutexWait(&mutexB
, 0);interruptByOtherTask(); tMutexWait(&mutexA
, 0);task2Flag
= 1;tTaskDelay(1);task2Flag
= 0;tTaskDelay(1);tMutexNotify(&mutexA
);tMutexNotify(&mutexB
);task2Flag
= 1;tTaskDelay(1);task2Flag
= 0;tTaskDelay(1);}
}
void task3Entry
(void *param
) {for (;;) {task3Flag
= 1;tTaskDelay(1);task3Flag
= 0;tTaskDelay(1);}
}
void task4Entry
(void *param
) {for (;;) {task4Flag
= 1;tTaskDelay(1);task4Flag
= 0;tTaskDelay(1);}
}
void tInitApp
(void) {halInit();tMutexInit(&mutexA
);tMutexInit(&mutexB
);tTaskInit(&task1
, task1Entry
, (void *) 0x0, TASK1_PRIO
, task1Env
, sizeof(task1Env
));tTaskInit(&task2
, task2Entry
, (void *) 0x0, TASK2_PRIO
, task2Env
, sizeof(task2Env
));tTaskInit(&task3
, task3Entry
, (void *) 0x0, TASK3_PRIO
, task3Env
, sizeof(task3Env
));tTaskInit(&task4
, task4Entry
, (void *) 0x0, TASK4_PRIO
, task4Env
, sizeof(task4Env
));
}
#include "tinyOS.h"
#include "app.h"
#include "hal.h"static tTask task1
;
static tTask task2
;
static tTask task3
;
static tTask task4
; static tTaskStack task1Env
[TASK1_ENV_SIZE
];
static tTaskStack task2Env
[TASK2_ENV_SIZE
];
static tTaskStack task3Env
[TASK3_ENV_SIZE
];
static tTaskStack task4Env
[TASK4_ENV_SIZE
]; int task1Flag
;
int task2Flag
;
int task3Flag
;
int task4Flag
; static tMutex mutexA
;
static tMutex mutexB
;
void task1Entry
(void *param
) {for (;;) {tMutexWait(&mutexA
, 0);interruptByOtherTask(); tMutexWait(&mutexB
, 0);task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1);tMutexNotify(&mutexB
);tMutexNotify(&mutexA
); task1Flag
= 1;tTaskDelay(1);task1Flag
= 0;tTaskDelay(1); }
}
void task2Entry
(void *param
) {for (;;) {tMutexWait(&mutexA
, 0);interruptByOtherTask(); tMutexWait(&mutexB
, 0);task2Flag
= 1;tTaskDelay(1);task2Flag
= 0;tTaskDelay(1);tMutexNotify(&mutexB
);tMutexNotify(&mutexA
);task2Flag
= 1;tTaskDelay(1);task2Flag
= 0;tTaskDelay(1);}
}
void task3Entry
(void *param
) {for (;;) {task3Flag
= 1;tTaskDelay(1);task3Flag
= 0;tTaskDelay(1);}
}
void task4Entry
(void *param
) {for (;;) {task4Flag
= 1;tTaskDelay(1);task4Flag
= 0;tTaskDelay(1);}
}
void tInitApp
(void) {halInit();tMutexInit(&mutexA
);tMutexInit(&mutexB
);tTaskInit(&task1
, task1Entry
, (void *) 0x0, TASK1_PRIO
, task1Env
, sizeof(task1Env
));tTaskInit(&task2
, task2Entry
, (void *) 0x0, TASK2_PRIO
, task2Env
, sizeof(task2Env
));tTaskInit(&task3
, task3Entry
, (void *) 0x0, TASK3_PRIO
, task3Env
, sizeof(task3Env
));tTaskInit(&task4
, task4Entry
, (void *) 0x0, TASK4_PRIO
, task4Env
, sizeof(task4Env
));
}
參考資料:
手把手教你學用嵌入式操作系統
總結
以上是生活随笔為你收集整理的多任务的死锁问题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。