一、死锁
- 线程 A 占用资源 1,线程 B 占用资源 2,线程 A 想占用资源 2,线程 B 想占用资源 1,线程 A 占用资源 1 的情况下去申请占用资源 2,线程 B 占用资源 2 的情况下去申请占用资源 1,就会出现互相等待对方释放资源的情况,也就是死锁。
- CPU 占用率 100% → 出现死循环或死锁。
- 死锁检测的算法底层逻辑:
- 有向图是否成环的问题。
- 线程 A 申请占用线程 B 的资源:A → B。
- 线程 B 申请占用线程 C 的资源:B → C。
- 线程 C 申请占用线程 A 的资源:C → A。
- 如何通过资源找到对应的线程 → 关系表(mtx ←→ thid)。
- 如何知道线程想占用资源 → 有向图。
- 有向图是否成环的问题。
二、核心代码
- 加锁之前。
void before_lock(pthread_t tid, pthread_mutex_t *mtx) {pthread_t otherid = search_rela_table(mtx);if (otherid != 0) {struct source_type from;from.id = tid;from.type = PROCESS;struct source_type to;to.id = otherid;to.type = PROCESS;add_edge(tid, otherid);} }
- 加锁之后。
void after_lock(pthread_t tid, pthread_mutex_t *mtx) {pthread_t otherid = search_rela_table(mtx);if (otherid != 0) {struct source_type from;from.id = tid;from.type = PROCESS;struct source_type to;to.id = otherid;to.type = PROCESS;if (verify_edge(from, to)) {remove_edge(from, to);}}add_rela_table(mtx, tid); }
- 解锁之后。
void after_unlock(pthread_t tid, pthread_mutex_t *mtx) {del_rela_table(mtx, tid); }
- 在关系表中增加一个关系。
int add_rela_table(pthread_mutex_t *mtx, pthread_t tid) {int i = 0;for (i = 0;i < MAX;i ++) {if ((rela_table[i].mtx == NULL) && (rela_table[i].thid