网站建设国家标准,wordpress wp_posts.myd 太大,淄博找能做网站的公司,设计师用的素材网站C线程库和POSIX线程库锁的区别 C线程库代码段的互斥#xff1a;mutex、recursive_mutex、timed_mutex、recursive_timed_mutex互斥量mutex#xff1a;直接进行lock()或者unlock()递归互斥锁recursive_mutex#xff1a;可以多次加锁#xff0c;意味着加几次锁就需要解几次锁… C线程库和POSIX线程库锁的区别 C线程库代码段的互斥mutex、recursive_mutex、timed_mutex、recursive_timed_mutex互斥量mutex直接进行lock()或者unlock()递归互斥锁recursive_mutex可以多次加锁意味着加几次锁就需要解几次锁定时互斥锁timed_mutex可以定时加锁规定什么时间让临界区代码实现互斥访问递归定时互斥锁recursive_timed_mutex在规定加锁时间的同时还能实现递归的多次加锁要求lock_guardRAII的方式封装了锁unique_lockRAII方式加锁/解锁 变量的原子性操作atomic POSIX线程库互斥锁pthread_mutex自旋锁pthread_spin读写锁pthread_rwlock C线程库
C线程库中提供了多种类型的原子性操作主要分为变量的原子性操作和代码段的互斥加锁
代码段的互斥mutex、recursive_mutex、timed_mutex、recursive_timed_mutex
如果一段代码是在多线程编程下执行的那么必然要涉及到线程安全的问题需要对该代码段进行加锁保护
#include iostream
#include mutex
#include thread
#include vectorstd::mutex g_mutex;
int g_count 0;void Counter() {g_mutex.lock();int i g_count;std::cout count: i std::endl;// 前面代码如有异常unlock 就调不到了。g_mutex.unlock();
}int main() {const std::size_t SIZE 4;// 创建一组线程。std::vectorstd::thread v;v.reserve(SIZE);for (std::size_t i 0; i SIZE; i) {v.emplace_back(Counter);}// 等待所有线程结束。for (std::thread t : v) {t.join();}return 0;
}
互斥量mutex直接进行lock()或者unlock()
上述例子中使用了mutex这个锁也就是c中提出的锁但是这样的方式导致一个线程执行g_count时其他线程在进行阻塞等待是有其自己的缺陷的
递归互斥锁recursive_mutex可以多次加锁意味着加几次锁就需要解几次锁
定时互斥锁timed_mutex可以定时加锁规定什么时间让临界区代码实现互斥访问
递归定时互斥锁recursive_timed_mutex在规定加锁时间的同时还能实现递归的多次加锁要求
lock_guardRAII的方式封装了锁
使用了RAII的思想让类对象1去管理锁资源在创建对象的时候加锁析构对象的时候解锁以此来预防死锁
unique_lockRAII方式加锁/解锁
除了使用RAII的思想之外还提供了加锁解锁修改锁的功能比lock_guard增加了一些对锁的操作
变量的原子性操作atomic int a 这个变量在整个多线程编程中如果是一个全局变量(局部变量也可以)那么当多个线程需要对其进行修改操作时必然涉及到线程安全的问题需要对这个变量加锁保护但是使用上述的mutex类型会显得大炮打苍蝇有点兴师动众了同时如果使用mutex加锁的方式来实现互斥会让其他线程处于阻塞等锁的状态会影响程序的效率 c11中提供了一系列原子操作
#include iostream
using namespace std;
#include thread
//需要包含对应的头文件
#include atomic
atomic_long sum{ 0 };
void fun(size_t num)
{for (size_t i 0; i num; i)sum ; // 原子操作
}
int main()
{cout Before joining, sum sum std::endl;thread t1(fun, 1000000);thread t2(fun, 1000000);t1.join();t2.join();cout After joining, sum sum std::endl;return 0;
}将普通变量修改为原子类型的变量这样就无需进行加锁解锁操作了会使代码的运行效率更高线程自己就能够对这些原子类型的变量实现互斥访问了
POSIX线程库
互斥锁pthread_mutex
有线程尝试加互斥锁时如果没有加到锁该线程会挂起并且切换只有当其他线程将该互斥锁释放之后该线程才会被唤醒继续加锁。
和C中的mutex相似可以对临界区代码进行加锁保护但是需要对该互斥锁初始化并且需要进行销毁
pthread_mutex_init()//初始化
pthread_mutex_lock()//加锁
pthread_mutex_unlock()//解锁
pthread_mutex_destroy()//销毁自旋锁pthread_spin
与互斥锁相比它的效率更高但是也更占CPU资源。
当有线程尝试加自旋锁时如果该线程没有加到锁那么会持续加锁直到拿到锁为止线程不会挂起也不会切换因此加锁效率高但也更加占用CPU资源
读写锁pthread_rwlock
当存在这样的场景时对数据的修改操作少有大量的读数据操作在这样的情况下对临界资源进行加锁会导致程序效率低下那么就需要有一个读不加锁而只有在写数据的时候才进行加锁来提高程序的效率读写锁就是这样一个锁 读共享写独占读锁优先级高