QT与C++中的线程/锁

Posted by Ada on December 5, 2018

最近在QT中要用多线程,记录一下。

线程安全:

几张图看懂进程、线程和锁

不过最早出处是阮一峰大佬的,我不知道为什么访问不了。

简单说来,如果cpu是一个工厂,进程(process)就是工厂里的车间。

一个车间里的许多工人就是不同的线程(thread)

车间的空间是工人们共享的(线程资源共享),比如房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。

有的房间(内存)一次只能一个人访问(线程)。必须等到当前线程访问结束,其它线程才能使用这块内存

为了防止访问冲突,可以加锁,先来的人上锁,后来的人看到上锁就排队。开锁以后再访问,这种锁就是互斥锁Mutex

对于能容纳n的人的房间(某些内存区域,只能供给固定数目的线程使用)。如果此时访问的数量超过n,多出来的就只能等待。

此时的方法是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做”信号量”(Semaphore),用来保证多个线程不会互相冲突。 不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。

QT中的锁 QMutex

QMutex提供提供线程之间访问顺序化。QMutex目的是保护一个对象,数据结构或者一段代码以至于同一时间只能有一个线程访问。

  • void QMutex::lock ()

    该函数用来锁住一个互斥量。如果另外的线程已经锁住了互斥量,函数将被阻塞等待另外的线程解锁互斥量。如果是一个可递归的互斥量,则可以从同一个线程多次调用这个函数,如果是非递归的互斥量,多次调用这个函数将会引发死锁

  • bool QMutex::tryLock ()

    该函数试图锁一个互斥量,如果成功则返回true。如果另外的线程已经锁住了互斥量,函数直接返回false

    • ool QMutex::tryLock ( int timeout )

      该函数跟上面的trylock()相似。不同的是,如果互斥量在别的线程锁住的情况下,函数会等待timeout 毫秒。需要注意的是,如果传入的timeout 为负数,函数将无限期等待,跟调用lock()一样的效果。

  • void QMutex::unlock ()

    该函数对互斥量进行解锁。如果在另外的线程加锁,尝试在别的线程进行解锁则会引发错误。试图对没有加锁的互斥量解锁结果是未定义的

    QMutexLocker

    QmutexLocker为了简化我们队互斥量的加锁和解锁操作。

    C++中的锁

    C++11里线程安全的模块是thread和mutex模块。使用也非常类似。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex g_lock;
void test()
{
	//g_lock.lock();
	std::cout << "hello"<<std::endl;
	std::cout << "World"<<std::endl;
	//g_lock.unlock();
}


int main()
{
	std::thread t1(test);

	std::thread t2(test);
	system("pause");
	return 0;
}

如果没有上锁,两个线程t1,t2执行同一个函数test()时。执行结果会是

hello

hello

world

world

如果上锁(取消注释)。就会是两行hello word。

关于线程安全这里,会是一个大的篇章,此文不定期更新


本站总访问量: