开发者

whether rand_r is real thread safe?

Well, rand_r function is supposed to be a thread safe function. However, by its implementation, I cannot believe it could make itself not change by other threads. Suppose that two threads will invoke rand_r in the same time with the same variable seed. So read-write race will occur. The code rand_r implemented by glibc is listed below. Anybody knows why rand_r is called thread safe?

 int
    rand_r (unsigned int *seed)
    {
      unsigned int next = *seed;
      int result;

      next *= 1103515245;
      next += 12345;
      result = (unsigned int) (next / 65536) % 2048;

      next *= 1103515245;
      next += 12345;
      result <<= 10;
      resu开发者_开发技巧lt ^= (unsigned int) (next / 65536) % 1024;

      next *= 1103515245;
      next += 12345;
      result <<= 10;
      result ^= (unsigned int) (next / 65536) % 1024;

      *seed = next;

      return result;
    }


You can think of three levels of thread safety, which I'll number here for ease of reference.

1) Not thread safe at all. It is unsafe to call the function concurrently from multiple threads. For example, strtok.

2) Thread safe with respect to the system. It is safe to call the function concurrently from multiple threads, provided that the different calls operate on different data. For example, rand_r, memcpy.

3) Thread safe with respect to data. It is safe to call the function concurrently from multiple threads, even acting on the same data. For example pthread_mutex_lock.

rand_r is at level 2, and the convention in the context of C (in particular in the POSIX specification) is to call this "thread safe".

In some other languages, such as Java, the convention is to refer to level 3 as "thread safe" and everything else as "not thread safe". So for example java.util.Vector is "thread safe" and java.util.ArrayList is "not thread safe". Of course all the methods of java.util.ArrayList are at level 2. So a programmer coming from Java might naturally call rand_r and memcpy "not thread safe".

In C the convention is different, perhaps because internally synchronised data structures are fairly rare to begin with. In the context of C you might ask "are file handles thread-safe?", and be talking about level 3, but when asking "is this function thread-safe?" that generally means level 2.


rand_r is thread safe is because the function is entirely pure. It doesn't read or modify any state other than the arguments. It can therefore be safely called concurrently.

This is different from most rand functions that hold the state (the seed) in a global variable.

Suppose that two threads will invoke rand_r in the same time with the same variable seed.

I am assuming you mean something like this

int globalSeed;

//thread 1
rand_r(&globalSeed);

//thread 2
rand_r(&globalSeed);

That doesn't mean that the function isn't thread safe, that just means you are using it in a non thread safe way by supplying an output parameter that may be accessed/modified by another thread.

It is the same thing as writing the function result to a global variable that may be accessed/modified by the another thread. It doesn't mean the function isn't thread safe, it means your code isn't thread safe.


Because it modifies seed and seed is passed in.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜