Между чтением вашего кода и вопросом я вижу большой концептуальный разрыв. В коде есть некоторые технические проблемы (например, вы никогда не закрываете); и трудно следовать последовательности.
Итак, этот шаблон:
pthread_create(&x, ?, func, arg);
pthread_join(x, ...);
Может быть заменен на:
func(arg);
, так что вы действительно не многопоточны в все; это точно так, как если бы:
void main(int argc, char *argv[]) // to avoid segmentation fault
{
size = atoi(argv[0]);
if (!(size >= 1))
{
printf("buffer size too small\n");
exit(0);
}
else
{
A[size].from = NULL;
A[size].to = NULL;
}
sec = atoi(argv[1]);
request_t(0);
lift(0);
lift(0);
lift(0);
}
и, зная это, я надеюсь, что вы видите бесполезность в:
pthread_mutex_lock(&lock);
....
pthread_mutex_unlock(&lock);
Итак, начните с небольшого переосмысления того, что вы делают. Похоже, у вас есть подъемное устройство, которое должно принимать входящие запросы, возможно, сортировать их, а затем обрабатывать. Вероятно, навсегда.
Это, вероятно, означает отсортированную очередь; однако один не отсортирован по обычным критериям. Лифт пересекает здание в обоих направлениях, но означает минимизацию изменений в направлении. Это включает в себя обход очереди как с порядком (>, <), так и с текущим направлением. Вы, вероятно, захотите запрос просто оценить график лифта и определить, куда вставить новый запрос. График лифта будет однонаправленным списком того, куда лиса пойдет дальше. И, возможно, правило, что список обращается только к своему списку, поскольку он останавливается на заданном этаже. </p>
Таким образом, Запрос может взять блокировку графа, изменить его, чтобы отразить новый запрос, а затем разблокировать его.
Подъемник может просто:
while (!Lift_is_decommissioned) {
pthread_mutex_lock(&glock);
Destination = RemoveHead(&graph);
pthread_mutex_unlock(&glock);
GoTo(Destination);
}
И запрос может быть:
pthread_mutex_lock(&glock);
NewDestination = NewEvent.floorpressed;
NewDirection = NewEvent.floorpressed > NewEvent.curfloor ? Up : Down;
i = FindInsertion(&graph, NewDestination, NewDirection);
InsertAt(&graph, i, NewDestination);
pthread_mutex_unlock(&glock);
Что может быть немного удивительно, что нет никакой разницы между нажатием " перейти на пол "изнутри лифта, и" Я хочу подняться здесь сейчас "снаружи лифта.
Но, с помощью такого рода разделения, вы можете сделать так, чтобы лифт просто следовал рецепту выше, и обработчики для кнопок вызывают другой псевдокод, приведенный выше.
FindInsertion () может быть немного неопрятным ....