инициализировать блокировку мьютекса pthread внутри структуры C - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь кодировать C проект для имитации управления воздушным движением c в авиакомпании. Существует структура Plane, которая должна иметь блокировку мьютекса и условия.

Это структура:

typedef struct Plane {
    int ID;
    int arrival_time;
    pthread_mutex_t lock;
    pthread_cond_t cond;
}Plane;

И есть функции посадки / вылета, которые создают и используют Plane структуры. , Однако я не знаю, как инициализировать блокировку мьютекса структуры внутри функции.

void landing_func(int arrival_time)
{
    Plane plane;
    plane.ID = ++plane_id;
    plane.arrival_time = arrival_time;
    // initialize lock and cond here

};

Однако я не уверен, как это сделать. Я также объявляю функцию, которая создает и возвращает Plane*

Plane* createPlane(int arrival_time){

    Plane* plane;
    plane = (Plane*)malloc(sizeof(Plane));
    plane->arrival_time = arrival_time;
    plane->ID = ++plane_id;
    pthread_mutex_init(&plane->lock, NULL);
    pthread_cond_init(&plane->cond, NULL);

    return plane;
};

Я не уверен в правильности этой инициализации.

Незначительный вопрос: могу ли я вернуть Plane вместо Plane*? Мне нужно Plane в других функциях вместо Plane*.

1 Ответ

0 голосов
/ 24 апреля 2020

Однако я не знаю, как инициализировать блокировку мьютекса структуры внутри функции.

Неясно, в чем заключается ваша путаница.

Переменная мьютекса и условия функции инициализации требуют в качестве первого аргумента указатель на объект для инициализации, что совершенно естественно. Их вторые аргументы могут быть нулевыми указателями, если вам нужны атрибуты по умолчанию, что вы, вероятно, делаете.

Учитывая

Plane plane;

, как и в первом примере, мьютекс, который вы хотите инициализировать, равен plane.lock. Оператор address-of выдаст указатель на него: &plane.lock (или, если вы не уверены в приоритетности и лень его искать, тогда &(plane.lock) избегает вопроса о приоритете). Таким образом, вы можете инициализировать его с помощью

pthread_mutex_init(&plane.lock, NULL);

Похоже на CV.

Я думаю, главное, что нужно оценить, это то, что мьютекс, являющийся членом структуры, не представляет собой особый случай , Объекты, которые являются членами структуры или элементами массива, имеют те же свойства, что и объекты того же типа, которые не содержатся в таких агрегатах. Разница лишь в том, как вы ссылаетесь на такие объекты.

Я также объявляю функцию, которая создает и возвращает Plane* [...] Я не уверен в правильности этой инициализации.

Это нормально, так как вы также сможете сделать вывод из моих предыдущих комментариев.

Небольшой вопрос: могу ли я вернуть Plane вместо Plane*? Мне нужно Plane в других функциях вместо Plane*.

Я так понимаю, что вы имеете в виду именно второй пример, где вы динамически выделяете пространство для Plane. Да, вы можете вернуть Plane вместо Plane *, предполагая, что вы корректируете тип возвращаемого значения функции, но это противоречит цели динамического распределения c. Более того, если вы сделаете это наивно (например, return *plane;), вы потеряете память.

Но очень важно понимать, что когда вы передаете или возвращаете объект, вы доставляете копия этого объекта получателю. Там, где когда-то был один, внезапно их два. * Кроме того, это мелкая копия, поэтому эти два могут быть не полностью независимыми. Это может быть хорошо при некоторых обстоятельствах, но ваши не такие обстоятельства. Я гарантирую, что прохождение ваших Plane структур таким образом не вызовет у вас конца печали в вашей конкретной программе, поскольку она зависит от мьютекса и CV, принадлежащих каждой. Там есть и другие ошибки, но мьютекс и резюме находятся в центре самых ярких.

Сделайте себе огромную пользу и настройте обмен Plane с помощью указателя, а не путем копирования. Это может потребовать некоторой корректировки, и у этого режима есть свои проблемы, но поверьте мне: другой путь ведет к катастрофе.


* Это относится так же, как это как указатели на объекты любого другого типа, но если вы передаете копию указателя, то копируется только сам указатель, и копия указывает на тот же объект, что и оригинал.

...