当前位置: 首页 > news >正文

网站建设中英语如何说如何建立一个网站

网站建设中英语如何说,如何建立一个网站,wordpress主题css修改,服务器做两个网站C11多线程编程 一:多线程概述 C11多线程编程 二:多线程通信,同步,锁 C11多线程编程 三:锁资源管理和条件变量 2.1 多线程的状态及其切换流程分析 线程状态说明: 初始化(Init)&am…

C++11多线程编程 一:多线程概述

C++11多线程编程 二:多线程通信,同步,锁

C++11多线程编程 三:锁资源管理和条件变量 


2.1 多线程的状态及其切换流程分析

线程状态说明:

        初始化(Init):该线程正在被创建。(就是创建thread对象并设置好回调函数,该线程就处在初始化状态,初始化线程的内存空间啊等,这部分其实代码干预部分不多,也就是从初始化,到就绪态之间其实是有一个时间消耗的,这就是为什么后面使用线程池来做一个处理,来减少时间消耗,当各种内存准备好之后,就变成就绪态了)
        就绪(Ready):不代表立刻就能运行了,该线程在就绪列表中,等待 CPU 调度。
        运行(Running):该线程正在运行。被CPU调度到了。
        阻塞(Blocked):该线程被阻塞挂起。Blocked 状态包括:pend(锁、 事件、信号量等阻塞)、suspend(主动 pend)、delay(延时阻塞)、 pendtime(因为锁、事件、信号量时间等超时等待)。阻塞态就是,CPU的调度已经不再这里了,放弃CPU的调度,不浪费资源。
        退出(Exit):该线程运行结束,等待父线程回收其控制块资源。


2.2 竞争状态和临界区介绍 互斥锁mutex代码

竞争状态(Race Condition): 多线程同时读写共享数据
临界区(Critical Section): 读写共享数据的代码片段
要避免竞争状态策略, 对临界区进行保护,同时只能有一个线程进入临界区。
 
例子:期望进行整块的输出,如下,
==============================
test 001
test 002
test 003
==============================
一共创建10个线程,那么我期望每个线程输出一个这样的整块屏幕输出。写如下代码:

但是最终的结果却不是想象的那样的,而出现了乱码。

这时候需要加一个mutex的锁(mutex是一个互斥锁),需要包含头文件:#include <mutex>
static mutex mux; mux叫做互斥变量。资源被上锁后,其他线程相当于是排队等待-阻塞
mux.lock是操作系统层面的锁,mux互斥锁只有这一个,线程主动过来处理的时候必须先抢占锁资源,所以线程它是一边抢占CPU资源一边抢占锁资源。

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
//Linux -lpthread
using namespace std;
static mutex mux;
void TestThread()
{for (;;){//获取锁资源,如果没有则阻塞等待//mux.lock(); //if (!mux.try_lock())  //try_lock()返回TRUE表示获得锁资源{cout << "." << flush;this_thread::sleep_for(100ms);continue;}cout << "==============================" << endl;cout << "test 001" << endl;cout << "test 002" << endl;cout << "test 003" << endl;cout << "==============================" << endl;mux.unlock();this_thread::sleep_for(1000ms);}
}
int main(int argc, char* argv[])
{for (int i = 0; i < 10; i++){thread th(TestThread);th.detach();}getchar();return 0;
}

 

这样就不会出现错误了,每次都是整块的输出,而不再有乱码了。


2.3 互斥锁的坑 线程抢占不到资源原因

理想状态,当一个线程释放锁资源之后,后面的线程会排队获取锁资源,但是实际上有时会出现一个线程始终占领着这个资源,其他线程排队永远获取不到资源的情况。

你会发现结果就是一直总是这一个或者两个线程进入,而不是理想的所有的线程都能得到展示,并不是我们想要的结果,原因如下:

        这段代码中,线程1获得锁资源的时候,线程2和线程3处于阻塞态,当线程1解锁的时候,按道理2号3号线程应该有一个立即获得锁资源的,但是对于线程1来说,当它解锁的时候,又重新进入了锁,也就是解锁后自己又重新申请了锁,这个锁是操作系统内核来判断,这个锁资源有没有被占用掉,当线程1解锁后,它的内存资源当然不是立即就被释放的,因为我们的操作系统不是实时操作系统,从解锁再到锁之间可能就是微秒级别的,而CPU调度肯定是过一段时间探测一下这个资源,当线程1解锁后立即又进入了锁,操作系统来不及反应,操作系统会认为是线程1又抢到了锁资源,实际上不是,而是因为线程1的资源还没有来得及释放就又重新进入锁了,所以它没有排队就再次进入了,所以这就是坑的所在,因此在解锁和锁之前要加一个延时,给操作系统做一个释放的时间。

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
//Linux -lpthread
using namespace std;
static mutex mux;void ThreadMainMux(int i)
{for (;;){mux.lock();cout << i << "[in]" << endl;this_thread::sleep_for(1000ms);mux.unlock();this_thread::sleep_for(1ms);}
}
int main(int argc, char* argv[])
{for (int i = 0; i < 3; i++){thread th(ThreadMainMux, i + 1);th.detach();}getchar();return 0;
}


2.4 超时锁timed_mutex(避免长时间死锁)和可重入锁

        mutex默认没有超时的,而有线程占用的情况下,其他线程是一直处于阻塞状态的,这种方式代码简洁,但是为后期的代码调试增加难度,比如说我们不小心在代码当中写了一个死锁,那你在调试当中你怎么去找到这个死锁呢?每次锁之前记录一下日志,看有没有进去,这样的调试成本比较大,不容易发现,只要加了timed就支持超时。

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
//Linux -lpthread
using namespace std;
timed_mutex tmux;void ThreadMainTime(int i)
{for (;;){if (!tmux.try_lock_for(chrono::milliseconds(500)))  //等待时间超过500ms就超时了{cout << i << "[try_lock_for timeout]" << endl;continue;}cout << i << "[in]" << endl;this_thread::sleep_for(2000ms);  //假设要处理的业务的持续时间tmux.unlock();this_thread::sleep_for(1ms);     //防止某一个线程一直占用这个锁资源}
}int main(int argc, char* argv[])
{for (int i = 0; i < 3; i++){thread th(ThreadMainTime, i + 1);th.detach();}getchar();return 0;
}

        很多业务可能会用到同一个锁,就会出现同一个锁被锁多次的情况,如果是普通的锁的话(mutex锁),第二次锁的时候会抛出异常,若没有捕获异常,那么程序就会崩溃掉,而这个递归锁可以进行多次上锁,他会把当前线程的锁计数加一,还是处于锁的状态不会改变,有多少次lock就会有多少次unlock,直到计数变成零的时候才真正释放,可以避免不必要的死锁。 

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
//Linux -lpthread
using namespace std;
recursive_mutex rmux;
void Task1()
{rmux.lock();cout << "task1 [in]" << endl;rmux.unlock();
}
void Task2()
{rmux.lock();cout << "task2 [in]" << endl;rmux.unlock();
}
void ThreadMainRec(int i)
{for (;;){rmux.lock();Task1();cout << i << "[in]" << endl;this_thread::sleep_for(2000ms);Task2();rmux.unlock();this_thread::sleep_for(1ms);}
}
int main(int argc, char* argv[])
{for (int i = 0; i < 3; i++){thread th(ThreadMainRec, i + 1);th.detach();}getchar();return 0;
}

2.5 共享锁shared_mutex解决读写问题

        当前线程在写数据的时候需要互斥,就是其他线程既不能写也不能读。当前线程在读的时候,其他线程只能读,不能写。
        这里面就涉及到两个锁,一个读的锁,一个写的锁,
若这个线程只读的话,那我们就用一个只读的锁就可以了,但是这个线程里面涉及到修改的时候,需要先拿到读的锁,然后再去获得写的锁,然后再修改,修改完之后再释放,用这种方式做一个共享。
        共享锁当中包含两个锁,一个是共享锁,一个是互斥锁,只要没有人锁定互斥锁,共享锁都是立即返回的,只要有人锁定了互斥锁,共享锁不能进,其他的互斥锁也不能进。
c++14 共享超时互斥锁 shared_timed_mutex(默认一般值支持到C++14)
c++17 共享互斥 shared_mutex
如果只有写时需要互斥,读取时不需要,用普通的锁的话如何做
按照如下代码,读取只能有一个线程进入,在很多业务场景中,没有充分利用 cpu 资源。

        原理是,如果有一个线程在写,其他所有线程既不能读也不能写,如果说有一个线程在读,其他线程都可以读,但不能写,必须等待所有的读线程读完之后才能写,这样就确保了资源不会被多人写而出现错误。
        这就是我们要用的共享锁。读取锁一定要先释放,读取锁如果锁住的话,互斥锁也是进不去的。互斥锁一旦进入,其他的所有读取线程都在等待。其他线程的写入锁也在等待,也既同时只能有一个线程在写入。

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
//c++17  共享锁
//shared_mutex smux;//c++14  共享锁 
shared_timed_mutex stmux;void ThreadRead(int i)
{for (;;){//stmux.lock_shared();共享锁,只要对方没有把互斥锁锁住,共享锁大家都可以进去。stmux.lock_shared();cout << i << " Read" << endl;this_thread::sleep_for(500ms);stmux.unlock_shared();this_thread::sleep_for(1ms);}
}
void ThreadWrite(int i)
{for (;;){stmux.lock_shared();//读取数据stmux.unlock_shared();stmux.lock(); //互斥锁 写入cout << i << " Write" << endl;this_thread::sleep_for(300ms);stmux.unlock();this_thread::sleep_for(1ms);}
}
int main(int argc, char* argv[])
{for (int i = 0; i < 3; i++){thread th(ThreadWrite, i + 1);th.detach();}for (int i = 0; i < 3; i++){thread th(ThreadRead, i + 1);th.detach();}getchar();return 0;
}

http://www.ds6.com.cn/news/18172.html

相关文章:

  • 企业网站建设总结百度扫一扫入口
  • 昆山建设银行网站首页百度免费广告发布平台
  • 做网站图片和文字字体侵权百度新闻排行榜
  • 建网站一定要备案吗如何做一个网站
  • 如何给公司做网站google官网注册
  • 中铁建设集团有限公司领导名单网站seo推广多少钱
  • 郑州市建设委员会网站金水湾免费建站建站abc网站
  • 中国网站建设公司百强微商刚起步怎么找客源
  • 承接网站建设广告语线上推广宣传方式有哪些
  • 查询公司的网站备案信息查询网络违法犯罪举报网站
  • 网站开发分为前端和后台直通车推广怎么做
  • 响应式网站开发pdf深圳债务优化公司
  • 云优cms搜索引擎优化是指什么
  • 济南做网站知识seo云优化公司
  • 东莞网站推广流程最新军事报道
  • 一个人做b2b2c网站医院网络销售要做什么
  • 免费进b站2023一键优化清理
  • 泗阳网站定制今日疫情最新消息
  • 东莞高端网站建设费用aso优化师
  • seo和sem的区别徐州seo代理计费
  • 网页设计实验报告精品课程网站网络营销收获与体会
  • 四川省的建设厅注册中心网站首页优化器
  • 西安南郊网站建设河源疫情最新通报
  • 眉山做网站武汉关键词排名工具
  • 找人做网站要拿到源代码吗站外推广免费网站
  • 深圳网站制作专业公司网络营销常见的工具
  • 哈尔滨做网站的oeminc微信裂变营销软件
  • 服装 公司 网站建设sem代运营
  • 网站挣钱网网站设计开发网站
  • 女教师遭网课入侵视频大全小璇seo优化网站