如何解决以下实现信号量同步的问题...
出于这个问题的目的,我们将对交叉路口进行建模,如上所示,将其划分为四分之一,并确定每个四分之一车道通过该部分进入交叉路口。(澄清一下:我们在道路的右侧行驶。)转弯表示通过交叉路口的一个、两个或三个部分的进展(为简单起见,假设在交叉路口不发生 U 形转弯) . 因此,如果一辆车从北方接近,根据它的去向,它会按如下方式通过十字路口:
| ! + ^ |
| ! + ! |
| v + ! |
--------------------------
<----|NW + NE| <----
| + |
++++++++++++++++++++++++++
| + |
----> |SW + SE| ---->
--------------------------
| ! + ^ |
| ! + ! |
| v + ! |
Right: NW
Straight: NW-SW
Left: NW-SW-SE
谁先到达路口,谁先行。
没有两辆车可以同时在交叉路口的同一部分。不要彼此通过相同的方式。如果两辆车从同一个方向接近并朝同一个方向行驶,那么最先到达交叉路口的汽车应该是最先到达目的地的汽车。同样,汽车不应该在十字路口相互“跳跃”。例如,假设一辆车进入十字路口并直行。然后另一辆车从同一方向进入交叉路口并向左行驶。第二辆车应该在第一辆车之后离开路口。然而,假设一辆车进入交叉路口并且向左行驶。如果另一辆车从同一方向进入交叉路口并向右行驶,那么它可能会更早离开交叉路口,因为第一辆车,即使它领先于第二辆车,可能还不能左转。每辆车在接近交叉口(接近)时应打印一条消息,进入交叉口的一个或多个区域((区域1),区域2和区域3),离开交叉口(离开),指示车号,接近方向和目的地方向。
从给定方向接近交叉路口的汽车应以相同的顺序进入交叉路口。请注意,在汽车接近交叉路口以减速之前不应进行同步。换句话说,不要在进入交叉路口的区域1之前简单地打印接近,例如,两个事件之间应该有一个同步原语。没有其他订购要求。例如,对于从不同方向接近的汽车,没有订购要求。我应该允许两辆或更多辆汽车同时进入十字路口,而不允许来自任何方向的交通使来自任何其他方向的交通饿死。
createcars 创建 20 辆汽车并将它们传递到接近交叉路口,为每辆汽车分配一个随机方向。我需要为他们分配一个随机的转弯方向;我也可以在接近交叉路口执行此操作。
其他例程 gostraight、turnright 和 turnleft 可能有助于或可能不会有助于实施此解决方案。我可以使用它们或丢弃它们。
这是一辆车(8 号车)从东方到达并朝西方行驶的示例输出。请注意,区域(例如,区域 1)是相对于每辆汽车定义的。向右行驶的汽车将输出 region1。直线行驶的汽车将输出 region1 和 region2。向左行驶的汽车将输出 region1、region2 和 region3。
approaching: car = 8, direction = E, destination = W
region1: car = 8, direction = E, destination = W
region2: car = 8, direction = E, destination = W
leaving: car = 8, direction = E, destination = W
以下是我的例程..
#include <types.h>
#include <lib.h>
#include <test.h>
#include <thread.h>
/*
* Number of cars created.
*/
#define NCARS 20
/*
*
* Function Definitions
*
*/
static const char *directions[] = { "N", "E", "S", "W" };
static const char *msgs[] = {
"approaching:",
"region1: ",
"region2: ",
"region3: ",
"leaving: "
};
/* use these constants for the first parameter of message */
enum { APPROACHING, REGION1, REGION2, REGION3, LEAVING };
static void
message(int msg_nr, int carnumber, int cardirection, int destdirection)
{
kprintf("%s car = %2d, direction = %s, destination = %s\n",
msgs[msg_nr], carnumber,
directions[cardirection], directions[destdirection]);
}
/*
* gostraight()
*
* Arguments:
* unsigned long cardirection: the direction from which the car
* approaches the intersection.
* unsigned long carnumber: the car id number for printing purposes.
*
* Returns:
* nothing.
*
* Notes:
* This function should implement passing straight through the
* intersection from any direction.
* Write and comment this function.
*/
static void gostraight(unsigned long cardirection, unsigned long carnumber)
{
/*
* Avoid unused variable warnings.
*/
(void) cardirection;
(void) carnumber;
}
/*
* turnleft()
*
* Arguments:
* unsigned long cardirection: the direction from which the car
* approaches the intersection.
* unsigned long carnumber: the car id number for printing purposes.
*
* Returns:
* nothing.
*
* Notes:
* This function should implement making a left turn through the
* intersection from any direction.
* Write and comment this function.
*/
static void turnleft(unsigned long cardirection, unsigned long carnumber)
{
/*
* Avoid unused variable warnings.
*/
(void) cardirection;
(void) carnumber;
}
/*
* turnright()
*
* Arguments:
* unsigned long cardirection: the direction from which the car
* approaches the intersection.
* unsigned long carnumber: the car id number for printing purposes.
*
* Returns:
* nothing.
*
* Notes:
* This function should implement making a right turn through the
* intersection from any direction.
* Write and comment this function.
*/
static void turnright(unsigned long cardirection, unsigned long carnumber)
{
/*
* Avoid unused variable warnings.
*/
(void) cardirection;
(void) carnumber;
}
/*
* approachintersection()
*
* Arguments:
* void * unusedpointer: currently unused.
* unsigned long carnumber: holds car id number.
*
* Returns:
* nothing.
*
* Notes:
* I need to change this function to implement sempahore synchronization. These
* threads are created by createcars(). Each one must choose a direction
* randomly, approach the intersection, choose a turn randomly, and then
* complete that turn. The code to choose a direction randomly is
* provided, the rest is left to you to implement. Making a turn
* or going straight should be done by calling one of the functions
* above.
*/
static void approachintersection(void * unusedpointer, unsigned long carnumber)
{
int cardirection;
/*
* Avoid unused variable and function warnings.
*/
(void) unusedpointer;
(void) carnumber;
(void) gostraight;
(void) turnleft;
(void) turnright;
/*
* cardirection is set randomly.
*/
cardirection = random() % 4;
}
/*
* createcars()
*
* Arguments:
* int nargs: unused.
* char ** args: unused.
*
* Returns:
* 0 on success.
*
* Notes:
* Driver code to start up the approachintersection() threads.
* I can modify this code as well for my solution..
*/
int createcars(int nargs, char ** args)
{
int index, error;
/*
* Avoid unused variable warnings.
*/
(void) nargs;
(void) args;
/*
* Start NCARS approachintersection() threads.
*/
for (index = 0; index < NCARS; index++) {
error = thread_fork("approachintersection thread",
NULL,
index,
approachintersection,
NULL
);
/*
* panic() on error.
*/
if (error) {
panic("approachintersection: thread_fork failed: %s\n",
strerror(error)
);
}
}
return 0;
}
[1]: http://i.stack.imgur.com/1389H.gif