【Linux系统编程】线程池和C++线程安全
目录
一,线程池的说明
1-1,线程池与多线程
1-2,线程池的代码运用
二,C++与线程安全
一,线程池的说明
1-1,线程池与多线程
多线程是指在单个程序中同时运行多个线程,每个线程可以独立执行程序中的一部分代码。这些线程共享程序的内存空间和资源,但各自拥有独立的执行路径和栈空间。
线程池是一种线程管理技术,它预先创建并维护一组线程(即线程池),当需要执行新任务时,从线程池中取出一个空闲线程来执行任务,而不是创建一个新线程。任务执行完毕后,线程不会销毁,而是回到线程池中等待下一个任务。
注意:多线程都是遇到任务然后创建线程再执行,但是线程的频繁创建就类似于内存的频繁申请,导致线程在短时间内的频繁创建与销毁,给操作系统带来更大的压力,进而影响整体的性能。线程池是一次性申请好一定数量的线程,这些线程等待着监督管理者(线程池)分配可并发执行的任务,这样避免了线程在短时间内不断创建与销毁线程的代价,但线程池中的线程数量是有限的,如果任务数量过多,可能会导致任务等待时间变长。因此,对于需要频繁创建和销毁线程的场景,线程池是一个更好的选择;而对于任务数量较少或需要高度自定义线程管理的场景,多线程可能更合适。
1-2,线程池的代码运用
相关说明:
我们创建好了线程池之后,首次我们先是对其进行初始化操作,然后不断的向任务队列塞数据,由线程池中的线程去获取任务并执行相关操作:
1,任务队列(即临界资源)是会被多个执行流同时访问,因此我们需要引入互斥锁对任务队列进行保护。
2,线程池中的线程想要获取到任务队列中的任务,那么就必须要确保任务队列中有任务,所以我们还需引入条件变量来进行判断,如果队列中没有任务,线程池中的线程将会被挂起,直到任务队列中有任务后才被唤醒。
3,在线程池中,多线程去执行对应的方法的时候,采用的是静态成员函数,这样做的目的是解决类中存在隐藏的this指针问题,因为线程池初始化 pthread_create 创建线程时,该函数只有一个形参,不加static的话,那么形参个数就有两个,这样会导致编译出错。运用静态函数,我们可以将this指针作为参数传递过去,就可以访问类内的成员函数了。
代码演示请在此链接下查看:Linux线程池
二,C++与线程安全
STL与线程安全:
STL中的容器不是线程安全。C++中的STL 的设计初衷是将性能挖掘到极致,而一旦涉及到加锁保证线程安全就会对性能造成巨大的影响,除此外,对于不同的容器,加锁方式的不同,性能可能也不同。因此,STL默认不是线程安全,如果需要在多线程环境下使用,往往需要调用者自行保证线程安全。
智能指针与线程安全:
对于 unique_ptr 智能指针,由于只是在当前代码块范围内生效,因此不涉及线程安全问题。
对于 shared_ptr 智能指针,由于多个对象需要共用一个引用计数变量,所以这里会存在线程安全问题,但是标准库实现的时候考虑到了这个问题,因此,C++标准库保证了引用计数是原子性,使其在多个线程中同时对一个 shared_ptr 实例的引用计数进行增加或减少操作是线程安全的。但是,shared_ptr 智能指针在访问其指向的对象以及进行拷贝和赋值操作时不是线程安全,需要额外的同步机制来确保线程安全。