質問

I have following code in my project at my work using 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);

I have following questions in above code.

  1. Is above code works as we are calling semGive even if semTake failed ?.

  2. When I talked to author I was told that we can call semGive even i semTake fails. Will it have any side effects?

  3. Is programming like above is good practice?

Thanks for inputs.

役に立ちましたか?

解決

First, since you're creating a binary semaphore, there is no "count" per se. The semaphore is either full or empty and there is no concept of ownership (like there would be for a mutex).

The thing that confuses me about this particular code is that the task running this function seems to signal itself.

There are two possible types of error returned here:

  • A Timeout (most likely)
  • A real error

I would hope that you do check the errno to determine which of those 2 cases you encounter. If the error is not a timeout, then you probably have a serious problem on your hands and almost certainly, the operations of the semaphore are totally compromised, in which case doing a semGive probably also fails.

If the error is a timeout (i.e. after 500 ticks) then your code should be fine.

If there is only a single task running this function (and there are no other tasks waiting on this same semaphore), then loops through the function would always succeed right away. In fact, in fact, I can't see how this would fail.

So I must deduce that there are multiple tasks waiting for the same semaphore.

Without more details, it's difficult to say for sure if the code will do what you want it to, but it's legal. It really depends on what happens in the "else" branch if it's not a timeout.

他のヒント

Is above code works as we are calling semGive even if semTake failed ?.

Depends on what you mean by "work".

When I talked to author I was told that we can call semGive even i semTake fails. Will it have any side effects?

Sure you can. You will increment the semaphore value even when you failed to grab the sempaphore. This is almost never what you want to do.

Is programming like above is good practice?

No, the code is confusing, and it's a bug that you release the semaphore even if you didn't acquire it.

You'd want to do

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

May not work as expected.

If SemTake is failed and you are calling SemGive(), SemGive() may or may not return success.

Note: SemGive() also fails with warning, count exceeded.

In the above code consider below cases.

  1. SemTake() failed and SemGive() failed.
  2. SemTake() failed and SemGive() returned success.

Your code give unexpected results in 2 case.

So SemGive() should be called only in the case of SemTake() returned success.

SemStatus = semTake(m_SemServState, 500);
    if(OK == SemStatus)
    {
        // ...
        semGive(m_SemServState);
    }
    else
    {
        //...
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top