Qt 线程安全类,可重入类,不可重入类,线程安全函数,可重入函数
2018-03-15 14:33
369 查看
Qt 线程安全类,可重入类,不可重入类,线程安全函数,可重入函数
我们首先对类进行说明,可以看成是递进关系,参考C++ GUI Qt 4 Programming。1、线程安全类:
不同线程对同一个类的对象进行操作,例如在不同线程调用同一个对象的类成员函数,是安全的,互不妨碍的,则说明该类是线程安全的,Qt中线程安全的类有QMutex、QMutexLocker、QReadWriteLock、QReadLocker、QWriteLocker、QSemaphore、QThreadStorage<T>以及QWaitCondition;2、可重入类:
可重入类只能保证可以在不同线程中操作不同的此类的对象是安全的,不能保证,不同线程操作同一个此类对象,是安全的;绝大多数Qt的非图形界面类都符合一个并不太严格的要求:它们都必须是可重入的,及类的不同实例可同时用于不同的线程中;很多Qt的非图形用户界面类,包括QImage、QString和一些容器类,都使用了隐式共享作为一项优化技术,虽然这样的优化通常会让类变成不可重入的,但是Qt使用原子汇编语言语言指令来实现线程安全引用计数,这可以让Qt的隐式共享类变成可重入的;3、不可重入类:
只能在一个线程中(一般是主线程)实例化对象,不能再其他线程中实例化该类的对象,可能是由于不同对象共享同一块内存,导致的;所有的QWidget和他的子类都是不可重入的,所以qt中的界面类实例化对象只能在主线程中,也不要试图把界面类对象的所属线程更改到子线程中,更不要在子线程中直接操作界面类对象,要使用信号与槽技术或者调用QMetaObject::invokeMethod(),具体原型参考Qt Assistant来实现在子线程中调用界面类的成员函数;
例如更改QLabel对象label的显示文本:void MyThread::run()
{
QMetaObject::invokeMethod(label, SLOT(setText(const QString &)), Q_ARG(QString, "Hello"));
}
可以看出,三个概念的安全系数是递减的关系。
对于函数的可重入,和类有些不同
可重入函数只是线程安全函数的一种,详见:http://blog.csdn.net/youngkingyj/article/details/24433733
在多线程编程和信号处理过程中,经常会遇到可重入(reentrance)与线程安全(thread-safe)。很多人纠结于reentrance和thread-safe两个概念理解纠缠不清。我想救我对reentrance和thread-safe的理解作个总结 一下以Posix协议的接口函数为例进行说明:一、可重入(reentrance)首先来看下APUE中,列出的可重入函数:
accept | fchmod | lseek | sendto | stat |
access | fchown | lstat | setgid | symlink |
aio_error | fcntl | mkdir | setpgid | sysconf |
aio_return | fdatasync | mkfifo | setsid | tcdrain |
aio_suspend | fork | open | setsockopt | tcflow |
alarm | fpathconf | pathconf | setuid | tcflush |
bind | fstat | pause | shutdown | tcgetattr |
cfgetispeed | fsync | pipe | sigaction | tcgetpgrp |
cfgetospeed | ftruncate | poll | sigaddset | tcsendbreak |
cfsetispeed | getegid | posix_trace_event | sigdelset | tcsetattr |
cfsetospeed | geteuid | pselect | sigemptyset | tcsetpgrp |
chdir | getgid | raise | sigfillset | time |
chmod | getgroups | read | sigismember | timer_getoverrun |
chown | getpeername | readlink | signal | timer_gettime |
clock_gettime | getpgrp | recv | sigpause | timer_settime |
close | getpid | recvfrom | sigpending | times |
connect | getppid | recvmsg | sigprocmask | umask |
creat | getsockname | rename | sigqueue | uname |
dup | getsockopt | rmdir | sigset | unlink |
dup2 | getuid | select | sigsuspend | utime |
execle | kill | sem_post | sem_post | wait |
execve | link | send | send | waitpid |
_Exit & _exit | listen | sendmsg | socketpair | write |
asctime | ecvt | gethostent | getutxline | putc_unlocked |
basename | encrypt | getlogin | gmtime | putchar_unlocked |
catgets | endgrent | getnetbyaddr | hcreate | putenv |
crypt | endpwent | getnetbyname | hdestroy | pututxline |
ctime | endutxent | getnetent | hsearch | rand |
dbm_clearerr | fcvt | getopt | inet_ntoa | readdir |
dbm_close | ftw | getprotobyname | l64a | setenv |
dbm_delete | gcvt | getprotobynumber | lgamma | setgrent |
dbm_error | getc_unlocked | getprotoent | lgammaf | setkey |
dbm_fetch | getchar_unlocked | getpwent | lgammal | setpwent |
dbm_firstkey | getdate | getpwnam | localeconv | setutxent |
dbm_nextkey | getenv | getpwuid | localtime | strerror |
dbm_open | getgrent | getservbyname | lrand48 | strtok |
dbm_store | getgrgid | getservbyport | mrand48 | ttyname |
dirname | getgrnam | getservent | nftw | unsetenv |
dlerror | gethostbyaddr | getutxent | nl_langinfo | wcstombs |
drand48 | gethostbyname | getutxid | ptsname | wctomb |
相关文章推荐
- 可重入函数和不可重入函数
- 不可重入函数与线程安全函数
- 什么是可重入函数和不可重入函数(转)
- 什么是可重入函数和不可重入函数(转)
- 可重如函数 不可重入函数 线程安全函数 线程不安全函数
- 什么是可重入函数和不可重入函数
- 可重入函数和不可重入函数
- 什么是可重入函数和不可重入函数(转)
- 关于可重入函数和不可重入函数
- 什么是可重入函数和不可重入函数以及区别
- 可重入函数,不可重入函数与线程安全
- 可重入函数和不可重入函数
- 什么是可重入函数和不可重入函数
- 可重入函数_不可重入函数
- 什么是可重入函数和不可重入函数
- C语言之可重入函数 && 不可重入函数
- 不可重入函数与线程安全函数
- 什么是可重入函数和不可重入函数(转)
- C语言之可重入函数 && 不可重入函数
- UNIX编程专题-可重入函数和不可重入函数