condition_variable 条件变量

10 篇文章 1 订阅
订阅专栏

条件变量

条件变量是允许多个线程相互交流的同步原语。它允许一定量的线程等待(可以定时)另一线程的提醒,然后再继续。条件变量始终关联到一个互斥。


头文件

<condition_variable>


condition_variable

condition_variable 类是同步原语,能用于阻塞一个线程,或同时阻塞多个线程,直至另一线程修改共享变量(条件)并通知 condition_variable 。

有意修改变量的线程必须(通知线程)

  1. 获得 std::mutex (典型地通过 std::lock_guard )
  2. 在保有锁时进行修改
  3. 在 std::condition_variable 上执行 notify_one 或 notify_all (不需要为通知保有锁)

即使共享变量是原子的,也必须在互斥下修改它,以正确地发布修改到等待的线程。

任何有意在 std::condition_variable 上等待的线程必须(等待线程)

  1. 获得 std::unique_lock<std::mutex> ,在与用于保护共享变量者相同的互斥上
  2. 执行 wait 、 wait_for 或 wait_until ,等待操作自动释放互斥,并悬挂线程的执行。
  3. condition_variable 被通知时,时限消失或虚假唤醒发生,线程被唤醒,且自动重获得互斥。之后线程应检查条件,若唤醒是虚假的,则继续等待。

std::condition_variable 只可与 std::unique_lock<std::mutex> 一同使用;此限制在一些平台上允许最大效率。 std::condition_variable_any 提供可与任何基础可锁 (BasicLockable) 对象,例如 std::shared_lock 一同使用的条件变量。

condition_variable 容许 wait 、 wait_for 、 wait_until 、 notify_one 及 notify_all 成员函数的同时调用。

类 std::condition_variable 是标准布局类型 (StandardLayoutType) 。它不可复制构造 (CopyConstructible) 、可移动构造 (MoveConstructible) 、可复制赋值 (CopyAssignable) 或可移动赋值 (MoveAssignable) 。


公共方法

名称描述
notify_one通知一个等待的线程
notify_all通知所有等待的线程
wait阻塞当前线程,直到条件变量被唤醒
wait_for阻塞当前线程,直到条件变量被唤醒,或到指定时限时长后
wait_until阻塞当前线程,直到条件变量被唤醒,或直到抵达指定时间点
native_handle返回原生句柄

wait


wait(_Lck)
流程图

在这里插入图片描述


示例
#include <iostream>
#include <condition_variable>

using namespace std;

mutex wait_mutex;
condition_variable wait_condition_variable;

// 等待线程函数
void wait_thread_func()
{
	unique_lock<mutex> lock(wait_mutex);
	cout << "等待线程(" << this_thread::get_id() << "): 开始等待通知..." << endl;
	wait_condition_variable.wait(lock);
	cout << "等待线程(" << this_thread::get_id() << "): 继续执行代码..." << endl;
}

int main()
{
	thread wait_thread(wait_thread_func);

	this_thread::sleep_for(1s); // 等待1秒后进行通知
	cout << "通知线程(" << this_thread::get_id() << "): 开始通知等待线程..." << endl;
	wait_condition_variable.notify_one();
	wait_thread.join();
	cout << "--- main结束 ---" << endl;
}
Output
等待线程(12348): 开始等待通知…
通知线程(15856): 开始通知等待线程…
等待线程(12348): 继续执行代码…
— main结束 —

错误示例:等待前通知,导致无法获得通知
#include <iostream>
#include <condition_variable>

using namespace std;

mutex wait_mutex;
condition_variable wait_condition_variable;

// 等待线程函数
void wait_thread_func()
{
    this_thread::sleep_for(1s); // 等待1秒后再等待通知
    
	unique_lock<mutex> lock(wait_mutex);
	cout << "等待线程(" << this_thread::get_id() << "): 开始等待通知..." << endl;
	wait_condition_variable.wait(lock);
	cout << "等待线程(" << this_thread::get_id() << "): 继续执行代码..." << endl;
}

int main()
{
	thread wait_thread(wait_thread_func);
	cout << "通知线程(" << this_thread::get_id() << "): 开始通知等待线程..." << endl;
	wait_condition_variable.notify_one();
	wait_thread.join();
	cout << "--- main结束 ---" << endl;
}
Output
通知线程(21892): 开始通知等待线程…
等待线程(2120): 开始等待通知…
(无限等待…)

wait(_Lck, _Pred)
流程图

在这里插入图片描述


示例:等待后通知
using namespace std;

mutex wait_mutex;
condition_variable wait_condition_variable;
bool ready = false;

// 等待线程函数
void wait_thread_func()
{
	// 等待通知再继续执行
	unique_lock<mutex> lock(wait_mutex);
	cout << "等待线程(" << this_thread::get_id() << "): 开始等待通知..." << endl;
	wait_condition_variable.wait(lock, [] { return ready; });
	cout << "等待线程(" << this_thread::get_id() << "): 继续执行代码..." << endl;
}

int main()
{
	thread wait_thread(wait_thread_func);

    this_thread::sleep_for(1s); // 等待1秒
	unique_lock<mutex> lock(wait_mutex);
	cout << "通知线程(" << this_thread::get_id() << "): 开始通知等待线程..." << endl;
	ready = true;
	lock.unlock(); // 不解锁的话,等待线程无法获得锁,则会进入死锁
	wait_condition_variable.notify_one();

	wait_thread.join();
	cout << "--- main结束 ---" << endl;
}
Output
等待线程(18172): 开始等待通知…
通知线程(19740): 开始通知等待线程…
等待线程(18172): 继续执行代码…
— main结束 —

示例:等待前通知
using namespace std;

mutex wait_mutex;
condition_variable wait_condition_variable;
bool ready = false;

// 等待线程函数
void wait_thread_func()
{
    this_thread::sleep_for(1s); // 等待1秒
    
	// 等待通知再继续执行
	unique_lock<mutex> lock(wait_mutex);
	cout << "等待线程(" << this_thread::get_id() << "): 开始等待通知..." << endl;
	wait_condition_variable.wait(lock, [] { return ready; });
	cout << "等待线程(" << this_thread::get_id() << "): 继续执行代码..." << endl;
}

int main()
{
	thread wait_thread(wait_thread_func);

	unique_lock<mutex> lock(wait_mutex);
	cout << "通知线程(" << this_thread::get_id() << "): 开始通知等待线程..." << endl;
	ready = true;
	lock.unlock(); // 不解锁的话,等待线程无法获得锁,则会进入死锁
	wait_condition_variable.notify_one();

	wait_thread.join();
	cout << "--- main结束 ---" << endl;
}
Output
通知线程(10972): 开始通知等待线程…
等待线程(22632): 开始等待通知…
等待线程(22632): 继续执行代码…
— main结束 —

错误示例:通知线程不加lock可能出现的问题
#include <iostream>
#include <condition_variable>

using namespace std;

mutex wait_mutex;
condition_variable wait_condition_variable;
bool ready = false;

// 等待线程函数
void wait_thread_func()
{
	// 等待通知再继续执行
	unique_lock<mutex> lock(wait_mutex);
	cout << "等待线程(" << this_thread::get_id() << "): 开始等待通知..." << endl;
	wait_condition_variable.wait(lock, []
		{
			bool state = ready;
			cout << "wait执行中(判断条件后,等待通知前)" << endl; // 模拟“wait执行中”
			this_thread::sleep_for(3s);
			return state;
		});
	cout << "等待线程(" << this_thread::get_id() << "): 继续执行代码..." << endl;
}

int main()
{
	thread wait_thread(wait_thread_func);

	this_thread::sleep_for(1s); // 模拟“wait执行中”进行通知

	//unique_lock<mutex> lock(wait_mutex);
	cout << "通知线程(" << this_thread::get_id() << "): 开始通知等待线程..." << endl;
	ready = true;
	//lock.unlock(); // 不解锁的话,等待线程无法获得锁,则会进入死锁
	wait_condition_variable.notify_one();

	wait_thread.join();
	cout << "--- main结束 ---" << endl;
}
Output
等待线程(19732): 开始等待通知…
wait执行中(判断条件后,等待通知前)
通知线程(6408): 开始通知等待线程…
(无限等待…)
解决方案:加入lock
#include <iostream>
#include <condition_variable>

using namespace std;

mutex wait_mutex;
condition_variable wait_condition_variable;
bool ready = false;

// 等待线程函数
void wait_thread_func()
{
	// 等待通知再继续执行
	unique_lock<mutex> lock(wait_mutex);
	cout << "等待线程(" << this_thread::get_id() << "): 开始等待通知..." << endl;
	wait_condition_variable.wait(lock, []
		{
			bool state = ready;
			cout << "wait执行中(判断条件后,等待通知前)" << endl; // 模拟“wait执行中”
			this_thread::sleep_for(3s);
			return state;
		});
	cout << "等待线程(" << this_thread::get_id() << "): 继续执行代码..." << endl;
}

int main()
{
	thread wait_thread(wait_thread_func);

	this_thread::sleep_for(1s); // 模拟“wait执行中”进行通知

	unique_lock<mutex> lock(wait_mutex);
	cout << "通知线程(" << this_thread::get_id() << "): 开始通知等待线程..." << endl;
	ready = true;
	lock.unlock(); // 不解锁的话,等待线程无法获得锁,则会进入死锁
	wait_condition_variable.notify_one();

	wait_thread.join();
	cout << "--- main结束 ---" << endl;
}
Output
等待线程(18072): 开始等待通知…
wait执行中(判断条件后,等待通知前)
通知线程(15672): 开始通知等待线程…
wait执行中(判断条件后,等待通知前)
等待线程(18072): 继续执行代码…
— main结束 —
总结

拥有lock:

只会在 “wait执行前/后” 进行通知

(通知后"等待线程"可以继续执行)

没有lock:

假如在 “wait执行中(判断条件后,等待通知前)” 进行通知,判断条件为false,并且无法受到通知(造成此次通知无效, “等待线程” 依然处于等待通知状态)


相关参考

微软文档(condition-variable)

cppreference(condition-variable)

C++11 并发指南五(stdcondition_variable 详解).docx
02-20
std::condition_variable 是 C++11 标准中 <condition_variable> 头文件里的一个类,用于实现条件变量的功能。条件变量是一种同步机制,允许线程在某个条件下等待或被唤醒。 std::condition_variable 的主要功能是...
并发与多线程(5) 条件变量 condition_variable
weixin_39354845的博客
10-31 530
条件变量 condition
C++中的condition_variable条件变量
Arman的博客
07-15 1221
在多线程编程中,我们常常需要一个线程等待某个条件的变化,比如等待数据的生成或某个标志位的设置。如果没有条件变量(),线程可能会使用忙等待(不断检查条件是否满足),这会导致 CPU 资源的浪费。条件变量提供了一种高效的等待机制,使线程在等待条件时进入休眠状态,不占用 CPU 资源,当条件满足时被唤醒继续执行。
C++ std::condition_variable
最新发布
m0_59680769的博客
07-30 916
是C++11引入的一个同步机制,主要用于在线程之间进行事件通知协调。它是标准库中的一个类,声明在头文件中。允许一个或多个线程等待另一个线程发送的信号(通过条件变量来实现的),从而基于某些条件进行协调动作。
C++ condition_variable
weixin_41502364的博客
10-16 94
条件变量同样是阻塞,还需要通知才能唤醒,线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,该线程就休眠了,应该仍阻塞在这里,等待条件满足后被唤醒,节省了线程不断运行浪费的资源。这种同步方式就是条件变量。两个线程操作同一临界区时,通过互斥锁保护,若A线程已经加锁,B线程再加锁时候会被阻塞,直到A释放锁,B再获得锁运行,线程B必须不停的主动获得锁、检查条件、释放锁、再获得锁、再检查、再释放,一直到满足运行的条件的时候才可以(而此过程中其他线程一直在等待该线程的结束),这种方式是比较消耗系统的资源的。
C++11条件变量使用详解
热门推荐
Keep Moving~
05-02 4万+
condition_variable介绍 在C++11中,我们可以使用条件变量condition_variable)实现多个线程间的同步操作;当条件不满足时,相关线程被一直阻塞,直到某种条件出现,这些线程才会被唤醒。 其主要成员函数如下: 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作: 一个线程因等待"条件变量的条件成立"而挂起; 另外一个线程使"条件成立",给出信...
条件变量(condition_variable)
个人工作中学到的专业技术与职业发展知识笔记
04-19 1万+
一、定义: 1.1、解释: 条件变量是利用线程间共享的变量进行同步的一种机制,是在多线程程序中用来实现"等待–>唤醒"逻辑常用的方法,用于维护一个条件(与是条件变量不同的概念),线程可以使用条件变量来等待某个条件为真,注意理解并不是等待条件变量为真。 当条件不满足时,线程将自己加入等待队列,同时释放持有的互斥锁; 当一个线程唤醒一个或多个等待线程时,此时条件不一定为真(虚假唤醒)。 1.2、个人理解: 两个线程利用条件变量及互斥锁实现同步。条件变量和互斥锁对两个线程来说是全局的。 一个线程利用条件变
C++多线程04:condition_variable条件变量
这是一个c++热爱者的博客哟
01-20 2993
在多线程编程中,有一种十分常见的行为:线程同步。线程同步是指线程间需要按照预定的先后次序顺序进行的行为。C++11对这种行为也提供了有力的支持,这就是条件变量(和条件变量位于头文件condition_variable下。类是一个,可用于阻止一个线程或同时阻止多个线程,直到另一个线程修改共享变量(condition),并通知condition_variable,才会继续执行。当调用它的wait函数时,它使用一个mutex来锁定线程。使得该线程保持阻塞状态,直到被另一个线程调用同一个。
C++ 多线程学习(3) ---- 条件变量
小猪佩奇的博客
06-30 7063
比如上面的代码中如果不加锁保护,在判断 mDisplayQueue.empty() 的条件成立后,此时线程被挂起,调度了另一个线程,另外的线程用于唤醒这个 condition_variable,此时当前线程因为还没有处于 wait 状态上(没有处于调度器的等待队列上),所以会丢失掉这个唤醒操作,如果这个唤醒操作只有一次,那么当前线程很可能永远处于阻塞等待的状态上。要解决该问题,就必须让生产者在缓冲区满时休眠,等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。
条件变量----condition_variable
weixin_44609676的博客
05-30 1197
和wait不同的是,wait_for可以执行一个时间段,在线程收到唤醒通知或者时间超时之前,该线程都会处于阻塞状态,如果收到唤醒通知或者时间超时,wait_for返回,剩下操作和wait类似。解锁正在等待当前条件的线程中的一个,如果没有线程在等待,则函数不执行任何操作,如果正在等待的线程多余一个,则唤醒的线程是不确定的。与wait_for类似,只是wait_until可以指定一个时间点,在当前线程收到通知或者指定的时间点超时之。解锁正在等待当前条件的所有线程,如果没有正在等待的线程,则函数不执行任何操作。
STL标准库之条件变量(condition_variable)
沉默、凝视的博客
10-08 1579
STL标准库线程同步条件变量的应用
condition_variable源码以及详细分析.docx
05-22
Condition_Variable 的构造函数中初始化了条件变量,并在析构函数中销毁了条件变量Condition_Variable 的 wait() 函数使用 pthread_cond_wait() 函数来实现等待操作,而 notify_one() 和 notify_all() 函数使用...
zm_condition_variable.zip
01-28
由于glibc早期版本的实现方式问题,导致在linux平台上使用c++条件变量(condition variable)时如果发生系统时间修改或跳变(向前),导致wait超时机制会阻塞,所以用select实现了一套跨平台的条件变量,已在项目中自测...
互斥锁与条件变量详解 疑问全解
08-11
条件变量Condition Variable)则是另一个重要的同步机制,它允许线程在满足特定条件时被唤醒或阻塞。下面,我们将详细解释互斥锁和条件变量的工作机制、使用场景和注意事项。 互斥锁(Mutex) 互斥锁是最基本的...
C++中自定义sleep、条件变量sleep实例
09-03
条件变量(`condition_variable`)是C++多线程编程中的另一个工具,它可以用来协调多个线程间的协作。条件变量允许一个线程在满足特定条件时等待,而其他线程可以改变这些条件并唤醒等待的线程。虽然在这个例子中...
C++ 11 深度学习(十七)condition_variable、wait
用可见的方式来记录和分享每一次收获
04-23 1万+
简介 条件变量std::condition_variable的作用是阻塞线程,然后等待通知将其唤醒。我们可以通过某个函数判断是否符合某种条件来决定是阻塞线程等待通知还是唤醒线程,由此实现线程间的同步。所以简单来说condition_variable的作用就两个——等待(wait)、通知(notify)。下面详细介绍一下。 等待线程 condition_variable的等待函数有三个,分别是wait()——等待、wait_for()——等待一段时间、wait_until()——等待至某一时刻。另外针
【C++入门到精通】condition_variable条件变量)C++11 [ C++入门 ]
Yawesh的博客
12-29 3900
这篇文章介绍了C++中的条件变量的用法和功能。文章简要介绍了条件变量的概念,解释了它是如何实现线程之间的同步和通信的;列举并解释了条件变量的三个主要成员函数:wait()、notify_one()和notify_all()。最后,给出了两个使用示例:使用条件变量实现生产者-消费者模型和两个线程交替打印奇数和偶数。通过这篇文章,读者将能够了解条件变量的基本概念、成员函数的用法,并通过示例代码理解如何在实际应用中使用条件变量来实现线程间的同步和通
C++11 condition_variable条件变量用法
kingforyang的博客
12-02 4849
C++11 condition_variable条件变量用法1 什么是条件变量2 condition_variable类定义2.1 wait函数3 condition_variable用法3.1 资源修改线程步骤3.2 资源等待线程步骤4 代码示例4.1 无需notify场景4.2 正常应用场景14.3 正常应用场景2 1 什么是条件变量 condition_variable是一个类,常和mutex搭配使用。 condition_variable类是一个同步原语,可用于阻塞一个线程或同时阻止多个线程,直到另
c++11 并发编程 --- 条件变量(condition_variable) wait,wait_for
无左无右的博客
10-20 9657
介绍condition_variable, wait,wait_for 直接上代码如下: #include <iostream> // std::cout #include <thread> // std::thread #include <mutex> // std::...
condition_variable_any和condition_variable有什么区别
08-24
condition_variable_any和condition_variable是C++标准库中的两个条件变量类,用于线程间的同步和通信。它们之间的区别主要在于以下两个方面: 1. 功能:condition_variable_any相比condition_variable更通用。condition_variable_any可以与任何互斥量(包括std::mutex和std::recursive_mutex等)一起使用,而condition_variable只能与std::unique_lock<std::mutex>一起使用。 2. 条件变量的所有权:condition_variable_any对条件变量的所有权没有限制,可以在多个线程之间传递。而condition_variable只能在单个线程中使用,不能在多个线程之间传递。 综上所述,如果你需要与不同类型的互斥量一起使用,并且需要在线程之间传递条件变量的所有权,那么可以选择condition_variable_any。否则,如果只需要与std::mutex一起使用,并且不需要在线程之间传递条件变量的所有权,那么使用condition_variable即可。
写文章

热门文章

  • condition_variable 条件变量 7714
  • C# 7.0本质论(设计规范) 3568
  • [Unity]免费的海洋系统Crest Ocean System 3560
  • 引用UnityEditor命名空间后无法编译 3448
  • [台服公主链接]提取global-metadata.dat 2870

分类专栏

  • Unity 34篇
  • Java
  • Frida 3篇
  • 安卓 6篇
  • Lua 1篇
  • 框架 1篇
  • Unity坑 7篇
  • C# 10篇
  • C++ 标准模板库 STL 10篇
  • 设计模式 5篇
  • 逆向分析 8篇

最新评论

  • 获取x-sign/x-mini-wua/x-sgext/x-umt

    ⁤冰⁤: 遇到过请求结果返回乱码的情况吗

  • Frida笔记

    阿虚同学W: frida -H 127.0.0.1:8080 com.jingdong.app.mall -l D:\PythonProjects\jd.js[这个是attach] 京东app,attach模式正常,但是spawn模式启动就会闪退是怎么回事呢?

  • condition_variable 条件变量

    freedom2211: 在【错误示例:通知线程不加lock可能出现的问题】中,bug与lock无关,是你的20行“this_thread::sleep_for(3s);”导致的,子线程无法接受的notify,睡过头了!

  • condition_variable 条件变量

    学渣技术帖: 两个等待前通知,有什么区别

  • 获取x-sign/x-mini-wua/x-sgext/x-umt

    火浴R: 已解决

大家在看

  • c++:类和对象(中)
  • c++primer第九章内存模型和名称空间学习笔记 759
  • C语言-rewind函数 1202
  • 基于django+vue基于B_S模式的智慧旅游管理信息系统【开题报告+程序+论文】-计算机毕设
  • 基于django+vue基于B_S架构的实验室开放管理系统【开题报告+程序+论文】-计算机毕设

最新文章

  • [学习日志]UI如何与数据绑定?
  • [学习日志]伤害生效由谁来决定?
  • [学习日志]记录一下自己设计ScriptableObject的一些思考
2022年3篇
2021年41篇
2019年15篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家浙江室内商场美陈销售公司玻璃钢花盆怎么养花宣城抽象玻璃钢雕塑山西创意玻璃钢雕塑生产厂家建邺商场大型美陈商场主题美陈图片户外玻璃钢雕塑订做山东通道商场美陈宿州抽象玻璃钢雕塑批发甘南玻璃钢动物雕塑公司玻璃钢雕塑可以放水里吗飞天女神玻璃钢雕塑山东户外商场美陈哪家好玻璃钢花盆惠新复材厂家上海室内商场美陈供货商山东开业商场美陈供应修武玻璃钢雕塑厂家玻璃钢商场美陈批发崇左玻璃钢雕塑江宁商场装饰美陈厦门广场玻璃钢人物雕塑批发仿古铜玻璃钢雕塑定做厂家平顶山天桥玻璃钢花盆供应商贵阳玻璃钢花盆厂家批发玻璃钢雕塑施工供应商义乌人物玻璃钢雕塑设计开远市玻璃钢雕塑设计如何上街区大型玻璃钢雕塑贵阳玻璃钢仿生雕塑南充玻璃钢商场美陈香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化