线程锁模拟交叉点
我试图使用线程和互斥锁来模拟交集.
我有去海峡的功能,左转,右转. 我为所有方向的所有汽车定义了所有锁. 采取进入海峡的功能.它有一个switch语句,可以打印当时汽车正在做什么.现在,我只是不确定锁定此功能的内容.如果汽车指向北方的方向,我将锁定东西方向,同时指向南方向北的汽车? 这是我的锁只调用一个锁定或解锁的功能 #define NUMCARS 30 #define lock_NW(CAR) lock(CAR,NW_mutex) #define lock_NE(CAR) lock(CAR,NE_mutex) #define lock_SW(CAR) lock(CAR,SW_mutex) #define lock_SE(CAR) lock(CAR,SE_mutex) #define unlock_NW(CAR) unlock(CAR,NW_mutex) #define unlock_NE(CAR) unlock(CAR,NE_mutex) #define unlock_SW(CAR) unlock(CAR,SW_mutex) #define unlock_SE(CAR) unlock(CAR,SE_mutex) 这里是主要的 int main(int argc,char **argv){ /* Initial variables*/ int index,tid; unsigned int carids[NUMCARS]; pthread_t carthreads[NUMCARS]; /* Start up a thread for each car*/ for(index = 0; index <NUMCARS; index++){ carids[index] = index; tid = pthread_create(&carthreads[index],NULL,approachintersection,(void*)&carids[index]); } /* Wait for every car thread to finish */ for(index = 0; index <NUMCARS; index++){ pthread_join(carthreads[index],NULL); } printf("Donen"); return 1; } 这是一个即将到来的交叉路口,它将功能称为海峡 static void * approachintersection(void* arg){ unsigned int * carnumberptr; unsigned int carnumber; orientation_t cardir = (orientation_t)random()%4; unsigned long turn = random()%3; carnumberptr = (unsigned int*) arg; carnumber = (unsigned int) *carnumberptr; if(turn==LEFT){ turnleft(cardir,carnumber); } else if(turn==RIGHT){ turnright(cardir,carnumber); } else {//straight gostraight(cardir,carnumber); } return (void*)carnumberptr; } 现在,这是我要锁定适当方向的海峡功能. /* cardirection - The direction the car is pointing. If it is pointing NORTH,it is starting from the South-Eastern corner of the intersection and "going straight" means it wants to move SOUTH to NORTH. valid options: NORTH,SOUTH,EAST,WEST carnumber - The car identifier */ static void gostraight(orientation_t cardirection,unsigned int carnumber){ switch(cardirection){ case NORTH: printf("Car %d,Moving South-Northn",carnumber); break; case SOUTH: printf("Car %d,Moving North-Southn",carnumber); break; case EAST: printf("Car %d,Moving West-Eastn",carnumber); break; case WEST: printf("Car %d,Moving East-Westn",carnumber); break; } } 因此,如果接近的汽车从南方指向北方,那么汽车将是SE汽车,我会用lock_SE(CAR)锁定箱子东,西打印功能?防止其他线程进入并打印?所以我会锁定解锁打印语句? 或者我会锁定整个switch语句? **编辑:这会是这样做的吗? ** static void turnleft(orientation_t cardirection,unsigned int carnumber){ int CAR; CAR = carnumber; switch(cardirection){ case NORTH: lock_SE(CAR) printf("Car %d,Moving South-Westn",carnumber); unlock_SE(CAR) break; case SOUTH: lock_NW(CAR) printf("Car %d,Moving North-Eastn",carnumber); unlock_NW(CAR) break; case EAST: lock_SW(CAR) printf("Car %d,Moving West-Northn",carnumber); unlock_SW(CAR) break; case WEST: lock_NE(CAR) printf("Car %d,Moving East-Southn",carnumber); unlock_NE(CAR) break; } } 解决方法
这不是一个容易的问题.我将尝试展示两种解决方案.
首先是明显的一个:一个互斥体用于整个交叉点,在转弯开始时,转弯,gostraight添加锁(car,intersection_mutex);,就在每个函数释放结束之前说的是互斥锁.这只会让一辆汽车一次穿过十字路口.这样做的好处是它易于理解,不会导致死锁.缺点是一次只能有一辆车进入,但众所周知,两辆行驶非交叉路径的车可以顺利进入. static void gostraight(orientation_t cardirection,unsigned int carnumber){ pthread_mutex_lock(&intersection_mutex); switch(cardirection){ case NORTH: printf("Car %d,carnumber); break; case SOUTH: printf("Car %d,carnumber); break; case EAST: printf("Car %d,carnumber); break; case WEST: printf("Car %d,carnumber); break; } } pthread_mutex_unlock(&intersection_mutex); } 为了让我们不止一辆车进入,我们需要一个细粒度的方法.细粒度方法的问题在于它更难实现并且变得更加正确. go_straight和turn_left都需要锁定两个互斥锁(你可以说左转需要三个……).因此,如果您无法获得这两个互斥锁,则需要退出.将其转化为驾驶规则: you must not enter the intersection before you can exit it. 所以,要直截了当,我们必须首先获得离您最近的互斥锁,然后是您路径中的下一个可以退出的互斥锁.如果我们无法获得两者,我们必须释放我们锁定的那个.如果我们不释放它,我们将死锁. 为此,我将添加两个辅助函数: static void lock_two(pthread_mutex_t *a,pthread_mutex_t *b) { while(1) { pthread_mutex_lock(a); if(pthread_mutex_trylock(b) == 0) break; else /* We must release the previously taken mutex so we don't dead lock the intersection */ pthread_mutex_unlock(a); pthread_yield(); /* so we don't spin over lock/try-lock failed */ } } static void unlock_two(pthread_mutex_t *a,pthread_mutex_t *b) { pthread_mutex_unlock(a); pthread_mutex_unlock(b); } 这是我直接的版本: static void gostraight(orientation_t cardirection,unsigned int carnumber){ switch(cardirection){ case NORTH: lock_two(&SE_mutex,&NE_mutex); printf("Car %d,carnumber); unlock_two(&SE_mutex,&NE_mutex); break; case SOUTH: lock_two(&NW_mutex,&SW_mutex); printf("Car %d,carnumber); unlock_two(&NW_mutex,&SW_mutex); break; case EAST: lock_two(&SW_mutex,&SE_mutex); printf("Car %d,carnumber); unlock_two(&SW_mutex,&SE_mutex); break; case WEST: lock_two(&NE_mutex,&NW_mutex); printf("Car %d,carnumber); unlock_two(&NE_mutex,&NW_mutex); break; } } turn_left然后需要遵循相同的方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |