Вы находитесь на странице: 1из 2

Mystery of Thread-safety and Rentrancy

A function can be either reentrant, thread-safe, both, or neither.


There are three main reasons for reentrancy to occur:
1. recursion
2. multi-threading
3. interruption (by interrupts/signals)

1. In most cases, to make a non-reentrant function reentrant, its external


interface must be modified such that all data is provided by the caller of the f
unction.
2. To make a thread-unsafe function thread-safe, only the implementation ne
eds to be changed, usually by adding synchronization blocks to protect shared re
sources from concurrent accesses by different threads.

int a=10; //global var


main()
{
for(i=0;i<10;i++)
increment();
}
void increment()
{
load a
increment a
store a
}
above code is
* NON-reentrant because if a signal interrupts one call after load
and the handler calls it again and returns, one increment is lost.
* NOT Thread-safe because if thread1 executing increment gets pree
mpted after load and thread2 calls it again and finishes the call one increment
is lost

int a=10; //global var


main()
{
for(i=0;i<10;i++)
increment();
}
void increment()
{
disable signals
load a
increment a
store a
disable signals
}
above code is
* re-entrant because it takes avoids being interrupted in an incon
sistent state by disabling interrupts and signals
* NOT Thread-safe because if thread1 executing increment gets pree
mpted after load and thread2 calls it again one increment is lost

int a=10; //global var


main()
{
for(i=0;i<10;i++)
increment();
}
void increment()
{
mutex lock
load a
increment a
store a
mutex unlock
}
above code is
* non-reentrant it gets interrupted after load a and ISR calls it
again one increment is lost (assuming the ownership of mutex and one thread can
lock the same mutex many times without unlocking it) pthread_mutexattr_settype(
&attr,
PTHREAD_MUTEX_RECURSIVE))
* thread-safe because it protects the critical section by a mutex.
int a=10; //global var
main()
{
for(i=0;i<10;i++)
a = increment(a);
}
int increment(int a)
{
load a
increment a
store a
return a
}
above code is
* reentrant because a is now local ( allocated on stack, separate
for each invocation )
* thread safe because a is now local ( allocated on stack, separat
e for each thread )

Вам также может понравиться