线程锁模拟交叉点

线程锁模拟交叉点,第1张

概述我试图使用线程和互斥锁来模拟交集. 我有去海峡的功能,左转,右转. 现在,我有一个接近十字路口的功能.这会产生随机方向并转向.每个线程共享接近的交叉点. 我为所有方向的所有汽车定义了所有锁. 采取进入海峡的功能.它有一个switch语句,可以打印当时汽车正在做什么.现在,我只是不确定锁定此功能的内容.如果汽车指向北方的方向,我将锁定东西方向,同时指向南方向北的汽车? 这是我的锁只调用一个锁定或解锁 我试图使用线程和互斥锁来模拟交集.

我有去海峡的功能,左转,右转.
现在,我有一个接近十字路口的功能.这会产生随机方向并转向.每个线程共享接近的交叉点.

我为所有方向的所有汽车定义了所有锁.

采取进入海峡的功能.它有一个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("Done\n");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 {//straightgostraight(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-north\n",carnumber);break;case SOUTH:printf("Car %d,Moving north-South\n",carnumber);break;case EAST:printf("Car %d,Moving West-East\n",carnumber);break;case WEST:printf("Car %d,Moving East-West\n",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-West\n",carnumber);  unlock_SE(CAR)  break;  case SOUTH:  lock_NW(CAR)  printf("Car %d,Moving north-East\n",carnumber);  unlock_NW(CAR)  break;  case EAST:  lock_SW(CAR)  printf("Car %d,Moving West-north\n",carnumber);  unlock_SW(CAR)  break;  case WEST:  lock_NE(CAR)  printf("Car %d,Moving East-South\n",carnumber);  unlock_NE(CAR)  break;  }

}

解决方法 这不是一个容易的问题.我将尝试展示两种解决方案.

首先是明显的一个:一个互斥体用于整个交叉点,在转弯开始时,转弯,gostraight添加锁(car,intersection_mutex);,就在每个函数释放结束之前说的是互斥锁.这只会让一辆汽车一次穿过十字路口.这样做的好处是它易于理解,不会导致死锁.缺点是一次只能有一辆车进入,但众所周知,两辆行驶非交叉路径的车可以顺利进入.
这是go_straight()的一个例子(其他人遵循相同的方法):

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然后需要遵循相同的方法.

总结

以上是内存溢出为你收集整理的线程锁模拟交叉点全部内容,希望文章能够帮你解决线程锁模拟交叉点所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1244196.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存