线程安全函数也是可重入函数,但可重入不一定是线程安全。
A thread-safe function is always reentrant, but a reentrant function is not always thread-safe.
线程安全函数:可以同步被多线程调用,即便访问了共享的数据,因为对共享数据的访问是序列化的。
可重入函数:仅在每个调用使用自己的数据时(如栈空间),才能被多线程调用。
(Qt对可重入函数的解释和其他地方的解释不同。)
作为扩展,一个类可重入,表示它的成员函数可以在多线程里调用,前提是每个线程使用一个不同的类对象。
一个类线程安全,表示多个线程可以同时调用其成员函数,即使这些线程使用的是同一个对象。
class Counter
{
public:
Counter() { n = 0; }
void increment() { ++n; }
void decrement() { --n; }
int value() const { return n; }
private:
int n;
};
上面的类是可重入的,但不是线程安全的。
因为++和--操作不是原子的,实际上通常需要3个机器指令:
1. 将变量的值载入到寄存器中;
2.改变寄存器的值;
3.把寄存的值写回到变量中。
如果线程A和线程B同时载入了变量的值,然后增1,结果是值只被增加1次。
下面的类是线程安全的:
class Counter
{
public:
Counter() { n = 0; }
void increment() { QMutexLocker locker(&mutex); ++n; }
void decrement() { QMutexLocker locker(&mutex); --n; }
int value() const { QMutexLocker locker(&mutex); return n; }
private:
mutable QMutex mutex;
int n;
};
Qt的许多类都是可重入的,但不是线程安全的。要做到线程安全,就要加很多的锁,这会影响性能。
注意:Qt的类只有被明确标为线程安全(thread-safe),才可以在多线程里使用。
网友评论