ashok v
ashok v

Reputation: 408

Is my function thread-safe and reentrant?

I have a function that is called by two threads each having a local copy of a vector. My Assumption was that since each thread has a different vector the function below is thread-safe.
Is the below function thread-safe and reentrant?

int Partition(int high, int low, int pivot, std::vector<int>& arr)
{
    int j = low;
    for (int i = low ; i <= high ; i++)
    {
        if (arr[i] <= pivot)
        {

            swap(i , j++ , arr);

        }
    }
    return arr.size() - j;
}

void swap(int fromIndex , int toIndex , std::vector<int> &arr)
{
    arr[fromIndex] = arr[fromIndex]^arr[toIndex];
    arr[toIndex] = arr[fromIndex]^arr[toIndex];
    arr[fromIndex] = arr[fromIndex]^arr[toIndex];
}

Upvotes: 3

Views: 260

Answers (2)

gyosifov
gyosifov

Reputation: 3223

A function is not thread safe if it changes shared memory among thread instances. If you have two different objects (not pointers) to vectors, then you don't have to worry.

If you want to make it thread safe you can use mutexes for instance:

#include <thread>         // std::thread
#include <mutex>          // std::mutex

std::mutex mtx;           // mutex for critical section

int Partition(int high, int low, int pivot, std::vector<int>& arr)
{
    int j = low;
    for (int i = low ; i <= high ; i++)
    {
        if (arr[i] <= pivot)
        {
            mtx.lock();
            swap(i , j++ , arr);
            mtx.unlock();
        }
    }
    return arr.size() - j;
}

More about mutex can be found here

Upvotes: 2

The function itself is not thread-safe, because it is possible to pass the same vector to it from different threads.

However, it is possible to write thread-safe code using non-thread-safe functions if you do the synchronization outside of these functions. I.e. if your calling code takes care that the same vector is never passed to that function at the same time, then the calling code would be thread-safe.

About being re-entrant, Wikipedia has the following to say:

In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution. The interruption could be caused by an internal action such as a jump or call, or by an external action such as a hardware interrupt or signal. Once the reentered invocation completes, the previous invocations will resume correct execution.

I emphasized the last part in that definition, because obviously, a function that is not thread-safe may not execute correctly and therefore cannot be reentrant by that definition.

Upvotes: 4

Related Questions