можно вызвать semGive, если в Vxworks5.5 произошел сбой semTake

0

У меня есть код в моем проекте на моей работе, используя 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);

У меня есть следующие вопросы в приведенном выше коде.

  1. Над кодом работает, поскольку мы вызываем semGive, даже если semTake не удалось?.

  2. Когда я поговорил с автором, мне сказали, что мы можем вызвать semGive, даже если semTake не удался. Будут ли какие-либо побочные эффекты?

  3. Является ли программирование, как указано выше, хорошей практикой?

Спасибо за вклад.

Теги:
vxworks

3 ответа

1
Лучший ответ

Во-первых, поскольку вы создаете двоичный семафор, нет "подсчета" как такового. Семафор является полным или пустым, и нет понятия собственности (например, для мьютекса).

То, что меня смущает об этом конкретном коде, заключается в том, что задача, выполняющая эту функцию, кажется, сигнализирует сам.

Здесь возможны два типа ошибок:

  • Тайм-аут (скорее всего)
  • Реальная ошибка

Я надеюсь, что вы проверите errno, чтобы определить, из каких двух случаев вы сталкиваетесь. Если ошибка не является таймаутом, у вас, вероятно, есть серьезная проблема на ваших руках, и почти наверняка операции семафора полностью скомпрометированы, и в этом случае выполнение semGive, вероятно, также не удастся.

Если ошибка является таймаутом (т.е. После 500 тиков), тогда ваш код должен быть в порядке.

Если есть только одна задача, выполняющая эту функцию (и нет других задач, ожидающих на этом же семафоре), тогда циклы через функцию всегда будут иметь успех сразу. Фактически, на самом деле, я не вижу, как это провалится.

Поэтому я должен вывести, что есть несколько задач, ожидающих того же семафора.

Без подробностей трудно сказать наверняка, будет ли код делать то, что вы хотите, но он легален. Это действительно зависит от того, что происходит в ветке else, если это не тайм-аут.

0

Может работать не так, как ожидалось.

Если SemTake не работает, и вы вызываете SemGive(), SemGive() может или не может вернуть успех.

Примечание: SemGive() также не работает с предупреждением, превышен счетчик.

В приведенном выше коде рассмотрим ниже случаи.

  1. Ошибка SemTake() и SemGive().
  2. SemTake() не удалось, и SemGive() вернул успех.

Ваш код дает неожиданные результаты в 2 случаях.

Поэтому SemGive() следует вызывать только в случае успеха SemTake().

SemStatus = semTake(m_SemServState, 500);
    if(OK == SemStatus)
    {
        // ...
        semGive(m_SemServState);
    }
    else
    {
        //...
    }
0

Над кодом работает, поскольку мы вызываем semGive, даже если semTake не удалось?.

Зависит от того, что вы подразумеваете под "работой".

Когда я поговорил с автором, мне сказали, что мы можем вызвать semGive, даже если semTake не удался. Будут ли какие-либо побочные эффекты?

Что вы можете. Вы увеличиваете значение семафора, даже если вам не удалось захватить sempaphore. Это почти никогда не то, что вы хотите сделать.

Является ли программирование, как указано выше, хорошей практикой?

Нет, код запутан, и это ошибка, которую вы выпускаете семафор, даже если вы ее не приобрели.

Вы хотите сделать

SemStatus = semTake(m_SemServState, 500);
if(OK == SemStatus)
{
    // ...
   semGive(m_SemServState);
}
else
{
    //...
}
  • 0
    @ это сработает, значит сиснорнизация будет работать как положено?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню