У меня есть следующий код в моем проекте на моей работе с использованием Vxworks5.5
m_SemServState = semBCreate(SEM_Q_FIFO, SEM_FULL );
//.... In another function I have following code.
SemStatus = semTake(m_SemServState, 500);
if(OK == SemStatus)
{
// ...
}
else
{
//...
}
semGive(m_SemServState);
У меня есть следующие вопросы в приведенном выше коде.
Выше код работает, как мы называем semGive, даже если semTake не удалось?
Когда я говорил с автором, мне сказали, что мы можем вызвать semGive, даже если semTake потерпит неудачу. Будет ли у него какие-либо побочные эффекты?
Является ли программирование, как указано выше, хорошей практикой?
Спасибо за вклад.
Во-первых, поскольку вы создаете двоичный семафор, «отсчета» как такового нет. Семафор либо полный, либо пустой, и нет понятия владения (как в случае мьютекса).
В этом конкретном коде меня смущает то, что задача, выполняющая эту функцию, похоже, сигнализирует сама о себе.
Здесь возможны два типа ошибок:
Я надеюсь, что вы проверите errno, чтобы определить, с каким из этих двух случаев вы столкнулись.
Если ошибка не по истечении времени ожидания у вас, вероятно, возникнет серьезная проблема, и почти наверняка операции семафора полностью скомпрометированы, и в этом случае выполнение semGive, вероятно, также завершится неудачей.
Если ошибка является тайм-аутом (т.е. после 500 тиков), тогда ваш код должен быть в порядке.
Если есть только одна задача, выполняющая эту функцию (и нет других задач, ожидающих на том же семафоре), то циклическое выполнение этой функции всегда будет выполнено сразу же. На самом деле, на самом деле, я не вижу, как это потерпит неудачу.
Поэтому я должен сделать вывод, что есть несколько задач, ожидающих одного и того же семафора.
Без подробностей трудно сказать наверняка, будет ли код делать то, что вы хотите, но это законно.
Это действительно зависит от того, что происходит в ветке «else», если это не тайм-аут.
Выше код работает, как мы называем semGive, даже если semTake не удалось?
Зависит от того, что вы подразумеваете под «работой».
Когда я говорил с автором, мне сказали, что мы можем вызвать semGive, даже если semTake потерпит неудачу. Будет ли у него какие-либо побочные эффекты?
Уверен ты Можно. Вы будете увеличивать значение семафора, даже если вам не удалось получить семафор. Это почти никогда не то, что вы хотите сделать.
Является ли программирование, как указано выше, хорошей практикой?
Нет, код сбивает с толку, и это ошибка, что вы выпускаете семафор даже
если ты не приобрел это.
Вы хотели бы сделать
SemStatus = semTake(m_SemServState, 500);
if(OK == SemStatus)
{
// ...
semGive(m_SemServState);
}
else
{
//...
}
Может работать не так, как ожидалось.
Если SemTake не удался и вы вызываете SemGive (), SemGive () может или не может вернуть успех.
Примечание: SemGive () также завершается с ошибкой, превышено количество.
В приведенном выше коде рассмотрим следующие случаи.
Ваш код дает неожиданные результаты в 2 случаях.
Поэтому SemGive () следует вызывать только в случае, если SemTake () вернул успех.
SemStatus = semTake(m_SemServState, 500);
if(OK == SemStatus)
{
// ...
semGive(m_SemServState);
}
else
{
//...
}