博客
关于我
生活中的死锁例子及解决办法
阅读量:796 次
发布时间:2023-03-28

本文共 10246 字,大约阅读时间需要 34 分钟。

为了实现十字路口交通的车辆同步问题,防止汽车在经过十字路口时产生死锁和饥饿,可以采用以下方案:

1. 车辆行为设计

每一辆车的行为设计为一个单独的线程。由于有四个不同方向的车辆,需要四种不同类型的线程。

2. 资源管理

使用 pthread 的互斥锁和条件变量解决车辆的同步与互斥。以下是所需资源:

  • 四个方向的互斥锁:mutex_a, mutex_b, mutex_c, mutex_d
  • 四个方向车辆队列的条件变量:cond_w, cond_e, cond_n, cond_s
  • 四个方向车辆队列的互斥锁:wait_north, wait_south, wait_east, wait_west
  • 四个方向车辆在十字路口的互斥锁:block_north, block_south, block_east, block_west
  • 四个方向车辆在队列中的条件变量:firstNorth, firstSouth, firstEast, firstWest
  • 死锁检测线程的条件变量:cond_deadlock
  • 死锁检测线程的互斥锁:mutex_e
  • 唤醒车辆的条件变量:cond_lock

3. 死锁检测与避免

设计一个死锁检测线程,当检测到死锁时,立即唤醒一辆车辆让其通过。死锁检测线程会等待所有车辆到达十字路口,并释放资源。

4. 饥饿防止

为了防止饥饿,设计以下机制:

  • 当一辆车辆通过十字路口后,发送一个信号给它左边等待的车辆,接下去让左边的车辆通行。
  • 设置下次通行车辆的条件变量:firstNorth, firstSouth, firstEast, firstWest

5. 车辆线程设计

每个方向的车辆线程如下:

  • 北向车:需要进入象限 ab
  • 东向车:需要进入象限 bc
  • 南向车:需要进入象限 cd
  • 西向车:需要进入象限 da

6. 代码实现

以下是实现车辆同步与互斥的代码:

#include 
#include
#include
#include
#include
#include
#define MAX 100// 四个方向的互斥锁pthread_mutex_t mutex_a = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mutex_b = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mutex_c = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mutex_d = PTHREAD_MUTEX_INITIALIZER;// 四个方向车辆队列的条件变量pthread_cond_t firstNorth = PTHREAD_COND_INITIALIZER;pthread_cond_t firstSouth = PTHREAD_COND_INITIALIZER;pthread_cond_t firstEast = PTHREAD_COND_INITIALIZER;pthread_cond_t firstWest = PTHREAD_COND_INITIALIZER;// 四个方向车辆队列的互斥锁pthread_mutex_t wait_north = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t wait_south = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t wait_east = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t wait_west = PTHREAD_MUTEX_INITIALIZER;// 四个方向车辆在十字路口的互斥锁pthread_mutex_t block_north = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t block_south = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t block_east = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t block_west = PTHREAD_MUTEX_INITIALIZER;// 死锁检测线程的互斥锁和条件变量pthread_cond_t cond_deadlock = PTHREAD_COND_INITIALIZER;pthread_mutex_t mutex_e = PTHREAD_MUTEX_INITIALIZER;// 唤醒车辆的条件变量pthread_cond_t cond_lock = PTHREAD_COND_INITIALIZER;typedef enum { west, north, south, east} dir_t;dir_t dir;int empty = 4;// 用于记录当前通过十字路口的车辆int current_north = 0;int current_south = 0;int current_east = 0;int current_west = 0;// 用于记录车辆的队列struct queue { pthread_t thread[MAX]; int num[MAX]; int front, rear; int count; queue() { front = rear = count = 0; } void push(int n) { count++; rear = (rear + 1) % MAX; num[rear] = n; } int pop() { count--; front = (front + 1) % MAX; return num[front]; }};queue car_north;queue car_south;queue car_east;queue car_west;bool is_north = false;bool is_south = false;bool is_east = false;bool is_west = false;bool is_deadlock = false;// 唤醒所有车辆void wakeupall() { is_deadlock = false; if (car_south.count > 0) { current_south = car_south.pop(); pthread_cond_signal(&firstSouth); } if (car_north.count > 0) { current_north = car_north.pop(); pthread_cond_signal(&firstNorth); } if (car_west.count > 0) { current_west = car_west.pop(); pthread_cond_signal(&firstWest); } if (car_east.count > 0) { current_east = car_east.pop(); pthread_cond_signal(&firstEast); }}// 北向车线程void* car_from_north(void* arg) { pthread_mutex_lock(&wait_north); pthread_cond_wait(&firstNorth, &wait_north); pthread_mutex_unlock(&wait_north); is_north = true; pthread_mutex_lock(&mutex_c); printf("车 %d 从北向车辆到达十字路口\n", current_north); empty--; dir = north; bool flag = false; if (empty == 0) { pthread_cond_signal(&cond_deadlock); pthread_cond_wait(&cond_lock, &mutex_c); usleep(2000); pthread_mutex_lock(&mutex_d); pthread_mutex_unlock(&mutex_c); printf("车 %d 从北向车辆离开十字路口\n", current_north); is_north = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_d); wakeupall(); return NULL; } else if (is_west) { flag = true; pthread_cond_wait(&cond_n, &block_north); if (is_deadlock) { usleep(2000); pthread_mutex_lock(&mutex_d); pthread_mutex_unlock(&mutex_c); printf("车 %d 从北向车辆离开十字路口\n", current_north); if (dir == east) { pthread_cond_signal(&cond_lock); } else { pthread_cond_signal(&cond_e); } is_north = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_d); return NULL; } } usleep(2000); pthread_mutex_lock(&mutex_d); if (car_west.count > 0 && flag) { current_west = car_west.pop(); pthread_cond_signal(&firstWest); } empty++; pthread_mutex_unlock(&mutex_c); is_north = false; printf("车 %d 从北向车辆离开十字路口\n", current_north); if (is_east) { pthread_cond_signal(&cond_e); } else if (!is_north && car_north.count > 0) { current_north = car_north.pop(); pthread_cond_signal(&firstNorth); } usleep(2000); pthread_mutex_unlock(&mutex_d);}// 南向车线程void* car_from_south(void* arg) { pthread_mutex_lock(&wait_south); pthread_cond_wait(&firstSouth, &wait_south); pthread_mutex_unlock(&wait_south); is_south = true; pthread_mutex_lock(&mutex_a); printf("车 %d 从南向车辆到达十字路口\n", current_south); empty--; dir = south; bool flag = false; if (empty == 0) { pthread_cond_signal(&cond_deadlock); pthread_cond_wait(&cond_lock, &mutex_a); usleep(2000); pthread_mutex_lock(&mutex_b); pthread_mutex_unlock(&mutex_a); printf("车 %d 从南向车辆离开十字路口\n", current_south); is_south = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_b); wakeupall(); return NULL; } else if (is_east) { flag = true; pthread_cond_wait(&cond_s, &block_south); if (is_deadlock) { usleep(2000); pthread_mutex_lock(&mutex_b); pthread_mutex_unlock(&mutex_a); printf("车 %d 从南向车辆离开十字路口\n", current_south); if (dir == west) { pthread_cond_signal(&cond_lock); } else { pthread_cond_signal(&cond_w); } is_south = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_b); return NULL; } } usleep(2000); pthread_mutex_lock(&mutex_b); if (car_east.count > 0 && flag) { current_east = car_east.pop(); pthread_cond_signal(&firstEast); } empty++; pthread_mutex_unlock(&mutex_a); is_south = false; printf("车 %d 从南向车辆离开十字路口\n", current_south); if (is_west) { pthread_cond_signal(&cond_w); } else if (!is_south && car_south.count > 0) { current_south = car_south.pop(); pthread_cond_signal(&firstSouth); } usleep(2000); pthread_mutex_unlock(&mutex_b);}// 东向车线程void* car_from_east(void* arg) { pthread_mutex_lock(&wait_east); pthread_cond_wait(&firstEast, &wait_east); pthread_mutex_unlock(&wait_east); is_east = true; pthread_mutex_lock(&mutex_b); printf("车 %d 从东向车辆到达十字路口\n", current_east); empty--; dir = east; bool flag = false; if (empty == 0) { pthread_cond_signal(&cond_deadlock); pthread_cond_wait(&cond_lock, &mutex_b); usleep(2000); pthread_mutex_lock(&mutex_c); pthread_mutex_unlock(&mutex_b); printf("车 %d 从东向车辆离开十字路口\n", current_east); is_east = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_c); wakeupall(); return NULL; } else if (is_north) { flag = true; pthread_cond_wait(&cond_e, &block_east); if (is_deadlock) { usleep(2000); pthread_mutex_lock(&mutex_c); pthread_mutex_unlock(&mutex_b); printf("车 %d 从东向车辆离开十字路口\n", current_east); if (dir == south) { pthread_cond_signal(&cond_lock); } else { pthread_cond_signal(&cond_s); } is_east = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_c); return NULL; } } usleep(2000); pthread_mutex_lock(&mutex_c); if (!is_north && car_north.count > 0 && flag) { current_north = car_north.pop(); pthread_cond_signal(&firstNorth); } empty++; pthread_mutex_unlock(&mutex_b); is_east = false; printf("车 %d 从东向车辆离开十字路口\n", current_east); if (is_east) { pthread_cond_signal(&cond_s); } else if (!is_east && car_east.count > 0) { current_east = car_east.pop(); pthread_cond_signal(&firstEast); } usleep(2000); pthread_mutex_unlock(&mutex_c);}// 西向车线程void* car_from_west(void* arg) { pthread_mutex_lock(&wait_west); pthread_cond_wait(&firstWest, &wait_west); pthread_mutex_unlock(&wait_west); is_west = true; pthread_mutex_lock(&mutex_d); printf("车 %d 从西向车辆到达十字路口\n", current_west); empty--; dir = west; bool flag = false; if (empty == 0) { pthread_cond_signal(&cond_deadlock); pthread_cond_wait(&cond_lock, &mutex_d); usleep(2000); pthread_mutex_lock(&mutex_a); pthread_mutex_unlock(&mutex_d); printf("车 %d 从西向车辆离开十字路口\n", current_west); is_west = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_a); wakeupall(); return NULL; } else if (is_south) { flag = true; pthread_cond_wait(&cond_w, &block_west); if (is_deadlock) { usleep(2000); pthread_mutex_lock(&mutex_a); pthread_mutex_unlock(&mutex_d); printf("车 %d 从西向车辆离开十字路口\n", current_west); if (dir == north) { pthread_cond_signal(&cond_lock); } else { pthread_cond_signal(&cond_n); } is_west = false; empty++; usleep(2000); pthread_mutex_unlock(&mutex_a); return NULL; } } usleep(2000); pthread_mutex_lock(&mutex_a); if (!is_north && car_north.count > 0 && flag) { current_north = car_north.pop(); pthread_cond_signal(&firstNorth); } empty++; pthread_mutex_unlock(&mutex_d); is_west = false; printf("车 %d 从西向车辆离开十字路口\n", current_west); if (is_north) { pthread_cond_signal(&cond_n); } else if (!is_west && car_west.count > 0) { current_west = car_west.pop(); pthread_cond_signal(&firstWest); } usleep(2000); pthread_mutex_unlock(&mutex_a);}// 死锁检测线程void* check_dead_lock(void* arg) { usleep(4000); wakeupall(); while (1) { pthread_mutex_lock(&mutex_e); pthread_cond_wait(&cond_deadlock, &mutex_e); is_deadlock = true; printf("DEADLOCK: 车辆拥堵,发送信号让车辆 %c 通行\n", dir); switch (dir) { case north: pthread_cond_signal(&cond_e); break; case east: pthread_cond_signal(&cond_s); break; case west: pthread_cond_signal(&cond_n); break; case south: pthread_cond_signal(&cond_w); break; } pthread_mutex_unlock(&mutex_e); }}int main(int argc, char** argv) { pthread_t check = pthread_create(&thread, NULL, &check_dead_lock, NULL); if (pthread_create(&car_north_thread, NULL, car_from_north, NULL) != 0) { perror("创建北向车线程失败"); return 1; } if (pthread_create(&car_south_thread, NULL, car_from_south, NULL) != 0) { perror("创建南向车线程失败"); return 1; } if (pthread_create(&car_east_thread, NULL, car_from_east, NULL) != 0) { perror("创建东向车线程失败"); return 1; } if (pthread_create(&car_west_thread, NULL, car_from_west, NULL) != 0) { perror("创建西向车线程失败"); return 1; } if (pthread_create(&check_deadlock_thread, NULL, check_dead_lock, NULL) != 0) { perror("创建死锁检测线程失败"); return 1; } sleep(1); return 0;}

7. 代码解释

  • 结构体和变量定义:定义了车辆队列、互斥锁、条件变量等。
  • 线程函数:每个方向的车辆线程负责到达十字路口的逻辑,包括互斥锁管理和条件变量等待。
  • 死锁检测线程:监测是否有死锁发生,并及时解除。
  • 主函数:初始化资源,创建各个车辆线程,并启动死锁检测线程。
  • 通过上述设计,可以有效避免死锁和饥饿问题,确保车辆能够顺利通过十字路口。

    转载地址:http://pphfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现字符串manacher马拉车算法(附完整源码)
    查看>>
    Objective-C实现字符串wildcard pattern matching通配符模式匹配算法(附完整源码)
    查看>>
    Objective-C实现字符串word patterns单词模式算法(附完整源码)
    查看>>
    Objective-C实现字符串Z 函数或 Z 算法(附完整源码)
    查看>>
    Objective-C实现字符串加解密(附完整源码)
    查看>>
    Objective-C实现字符串复制功能(附完整源码)
    查看>>
    Objective-C实现字符串是否回文Palindrome算法 (附完整源码)
    查看>>
    Objective-C实现字符串查找子串(附完整源码)
    查看>>
    Objective-C实现完整的ComplexNumber复数类(附完整源码)
    查看>>
    Objective-C实现实现rabin karp算法(附完整源码)
    查看>>
    Objective-C实现对图像进行色调处理算法(附完整源码)
    查看>>
    Objective-C实现对称矩阵压缩存储(附完整源码)
    查看>>
    Objective-C实现寻找欧拉路径/回路(附完整源码)
    查看>>
    Objective-C实现导弹跟踪算法(附完整源码)
    查看>>
    Objective-C实现将 base64 字符串转换为字节数组算法(附完整源码)
    查看>>
    Objective-C实现将位转换为浮点数bitsToFloat算法(附完整源码)
    查看>>
    Objective-C实现将列表向右旋转 k 个位置算法(附完整源码)
    查看>>
    Objective-C实现将字符串中大写字母转换为小写字母(附完整源码)
    查看>>
    Objective-C实现将字符串从一个基转换为另一个基算法(附完整源码)
    查看>>
    Objective-C实现将字节数组转换为 base64 编码算法(附完整源码)
    查看>>