boost教程(八):进程通信

每一部分都单独注释的,运行时取消注释,将其他部分注释起来就可以。

第一部分:共享内存

#include  
#include  
#include  
#include  





/*
查看Windows 6005 事件。开机启动时间
参考
https://stackoverflow.com/questions/39742630/boost-shared-memory-cant-be-initialized?r=SearchResults
共享内存通常是进程间通讯最快的形式。
*/
int test0()
{
	//创建之前,先检查有没得,删除了在创建
	/*
	多数Unix操作系统,包括Linux,一旦系统重新启动,都会自动删除共享内存,
	在 Windows 或 Mac OS X上,remove() 必须调用,这两种系统实际上将共享内存存储在持久化的文件上,
	此文件在系统重启后还是存在的。
	*/
	//boost::interprocess::shared_memory_object::remove("Highscore");
	//try
	//{
	/*
	************创建
	boost::interprocess::shared_memory_object 的构造函数需要三个参数。
	第一个参数指定共享内存是要创建或打开。
	第二个参数指定了这个名称。
	最后一个参数指示应用程序如何访问共享内存
	*/
		//boost::interprocess::shared_memory_object shdmem(boost::interprocess::open_or_create, "Highscore", boost::interprocess::read_write);

	//}
	//catch (const std::exception& ex)
	//{
		//std::cout << ex.what()<< std::endl;
	//}

	/*
	共享内存区域的大小被初始化为0.为了使用这块区域,需要调用 truncate() 函数,以字节为单位传递请求的共享内存的大小。
	truncate() 函数只能在共享内存以 boost::interprocess::read_write 方式打开时调用。 如果不是以此方式打开,
	将抛出 boost::interprocess::interprocess_exception 异常。
	truncate() 函数可以被重复调用
	*/
	//shdmem.truncate(1024);
	/*std::cout << shdmem.get_name() << std::endl;
	boost::interprocess::offset_t size;
	if (shdmem.get_size(size))
		std::cout << size << std::endl;*/




	/*
	***************映射
	 boost::interprocess::mapped_region 的构造函数的
	 第一个参数必须是 boost::interprocess::shared_memory_object 类型的对象。
	 第二个参数指示此内存区域对应用程序来说,是只读或是可写的。
	*/
	//boost::interprocess::mapped_region region(shdmem, boost::interprocess::read_write);
	//std::cout << std::hex << "0x" << region.get_address() << std::endl;
	//std::cout << std::dec << region.get_size() << std::endl;
	//boost::interprocess::mapped_region region2(shdmem, boost::interprocess::read_only);
	///*
	//被映射到进程的地址空间两次,get_address() 的返回值是不同的。
	//*/
	//std::cout << std::hex << "0x" << region2.get_address() << std::endl;
	//std::cout << std::dec << region2.get_size() << std::endl;


	/*
	***********写数据
	虽然变量 region 和 region2 表示的是该进程内不同的内存区域,
	但由于两个内存区域底层实际访问的是同一块共享内存,所以程序打印出99。
	在同一个应用程序内将同一个共享内存映射到不同的内存区域上没有多大的意义,下面的的例子只用于说明的目的。
	*/
	/*boost::interprocess::mapped_region region(shdmem, boost::interprocess::read_write);
	int *i1 = static_cast(region.get_address());
	*i1 = 99;
	boost::interprocess::mapped_region region2(shdmem, boost::interprocess::read_only);
	int *i2 = static_cast(region2.get_address());
	std::cout << *i2 << std::endl;*/





	//自动删除的共享内存
	/*
	boost::interprocess::windows_shared_memory 类是不可移植的,且只能用于Windows系统,
	但使用这种特别的共享内存在不同应用之间交换数据,它还是非常有用的。
	*/
	boost::interprocess::windows_shared_memory shdmem(boost::interprocess::open_or_create, "Highscore", boost::interprocess::read_write, 1024);
	boost::interprocess::mapped_region region(shdmem, boost::interprocess::read_write);
	int *i1 = static_cast<int*>(region.get_address());
	*i1 = 99;
	boost::interprocess::mapped_region region2(shdmem, boost::interprocess::read_only);
	int *i2 = static_cast<int*>(region2.get_address());
	std::cout << *i2 << std::endl;




	system("pause");
	return 0;
}

第二部分:托管共享内存

#include  
#include  

#include  
#include  
#include  


//参考
//http://zh.highscore.de/cpp/boost/interprocesscommunication.html

/*
boost::interprocess::shared_memory_object 类。
实际上,由于这个类需要按单个字节的方式读写共享内存,
所以这个类几乎不用。
*/


void construct_objects(boost::interprocess::managed_shared_memory &managed_shm)
{
	managed_shm.construct<int>("Integer")(99);
	managed_shm.construct<float>("Float")(3.14);
}

int test1()
{


	/*
	********************** 托管共享内存
	boost::interprocess::managed_shared_memory 类提供。 这个类的目的是,
	对于需要分配到共享内存上的对象,它能够以内存申请的方式初始化,并使其自动为使用同一个共享内存的其他应用程序可用。
	*/
	boost::interprocess::shared_memory_object::remove("Highscore");
	boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "Highscore", 1024);
	/*
	托管共享内存使用诸如 construct() 函数,此函数要求一个数据类型作为模板参数,此例中声明的是 int 类型,
	函数缺省要求一个名称来表示在共享内存中创建的对象。 此例中使用的名称是 "Integer"。
	construct() 函数返回一个代理对象,为了初始化创建的对象,可以传递参数给此函数

	*/
	//int *i = managed_shm.construct("Integer")[10](99);
	//std::cout << *i << std::endl;
	/*
	find() 实际返回的是 std::pair 类型的对象,
	first 属性提供的是指向对象的指针,
	那么 second 属性提供的是 它的值是数组元素的个数。
	*/
	/*std::pair p = managed_shm.find("Integer");
	if (p.first)
	{
		std::cout << *p.first << std::endl;
		std::cout << *(p.first+3) << std::endl;

		std::cout << p.second << std::endl;
	}*/


	/*
	如果给定名称的对象已经在托管的共享内存中存在,那么 construct() 将会失败。 在这种情况下,construct() 返回值是0。
	如果存在的对象即使存在也可以被重用,find_or_construct() 函数可以调用,
	此函数返回一个指向它找到的对象的指针。 此时没有初始化动作发生。
	*/

	//可以导致 construct() 失败的情况如下例所示。
	/*
	包含4,096个元素的数组。 然而,共享内存只有1,024 字节,
	*/
	/*try
	{
		boost::interprocess::shared_memory_object::remove("Highscore");
		boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "Highscore", 1024);
		int *i = managed_shm.construct("Integer")[4096](99);
	}
	catch (boost::interprocess::bad_alloc &ex)
	{
		std::cerr << ex.what() << std::endl;
	}*/



	/*
	*********删除共享内存对象
	*/

	/*int *i = managed_shm.find_or_construct("Integer")(99);
	std::cout << *i << std::endl;*/
	/*
	可以检查此函数的 bool 类型的返回值,以确定是否给定的对象被找到并成功删除。
	由于对象如果被找到总是被删除,所以返回值 false 表示给定名称的对象没有找到。
	*/
	/*managed_shm.destroy("Integer");
	std::pair p = managed_shm.find("Integer");
	std::cout << p.first << std::endl;*/


	/*
	为了创建在托管共享内存上申请内存的字符串,必须为 Boost.Interprocess 提供的另外一个分配器定义对应的数据类型,
	使用boost::interprocess::allocator这个类,可以创建一个分配器,此分配器的内部使用的是“托管共享内存段管理器”。
	段管理器负责管理位于托管共享内存之内的内存。 
	
	*/
	//typedef boost::interprocess::allocator CharAllocator;
	///*
	//新数据类型简单地命名为 string,它是基于 boost::interprocess::basic_string 并经过分配器访问段管理器。
	//*/
	//typedef boost::interprocess::basic_string, CharAllocator> string;
	///*
	//为了让通过 find_or_construct() 创建的 string 特定实例,知道哪个段管理器应该被访问,
	//相应的段管理器的指针传递给构造函数的第二个参数。

	//Boost.Interprocess 还提供了许多其他C++标准中已知的容器。 如, boost::interprocess::vector 和 boost::interprocess::map,
	//分别定义在 boost/interprocess/containers/vector.hpp 和 boost/interprocess/containers/map.hpp文件中
	//*/
	//string *s = managed_shm.find_or_construct("String")("Hello!", managed_shm.get_segment_manager());
	//s->insert(5, ", world");
	//std::cout << *s << std::endl;
	
	/*
	如果两个应用程序尝试在托管共享内存上创建不同名称的对象,访问相应地被串行化了。 
	为了立刻执行多个操作而不被其他应用程序的操作打断,可以使用 atomic_func() 函数。
	*/
	/*
	atomic_func() 需要一个无参数,无返回值的函数作为它的参数。
	被传递的函数将以以一种确保排他访问托管共享内存的方式被调用,但仅限于对象的创建,查找和销毁操作。
	如果另一个应用程序有一个指向托管内存中对象的指针,它还是可以使用这个指针修改该对象的。
	*/
	managed_shm.atomic_func(boost::bind(construct_objects, boost::ref(managed_shm)));
	std::cout << *managed_shm.find<int>("Integer").first << std::endl;
	std::cout << *managed_shm.find<float>("Float").first << std::endl;

	system("pause");
	return 0;

}

第三部分:同步

#include  
#include  
#include  

#include  

#include  
#include  







/*
Boost.Interprocess 提供了两种同步对象,
匿名对象被直接存储在共享内存上,这使得他们自动对所有应用程序可用。 
命名对象由操作系统管理,所以它们不存储在共享内存上,它们可以被应用程序通过名称访问。

*/
int main()
{

	//boost::interprocess::shared_memory_object::remove("shm");



	///**************命名互斥对象 
	//boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024);
	//int *i = managed_shm.find_or_construct("Integer")();
	///*
	//除了一个参数用来指定互斥对象是被创建或者打开之外,
	//boost::interprocess::named_mutex 创建并使用一个命名互斥对象,
	//boost::interprocess::named_mutex 的构造函数还需要一个名称参数。
	//每个知道此名称的应用程序能够访问这同一个对象。
	//*/
	//boost::interprocess::named_mutex named_mtx(boost::interprocess::open_or_create, "mtx");
	//named_mtx.lock();
	//++(*i);
	//std::cout << *i << std::endl;
	//named_mtx.unlock();

	///************匿名互斥对象
	//boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024);
	//int *i = managed_shm.find_or_construct("Integer")();
	///*
	//boost::interprocess::named_mutex 和 boost::interprocess::interprocess_mutex 
	//还提供了 try_lock() 和 timed_lock() 函数。 它们的行为和Boost.Thread提供的互斥对象相对应。
	//*/
	//boost::interprocess::interprocess_mutex *mtx = managed_shm.find_or_construct("mtx")();
	//mtx->lock();
	//++(*i);
	//std::cout << *i << std::endl;
	//mtx->unlock();


	/*
	条件变量的类型 boost::interprocess::named_condition,它是命名变量,所以它不需要存储在共享内存。
	
	*/

	//命名对象的条件锁
	/*boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024);
	int *i = managed_shm.find_or_construct("Integer")(0);
	boost::interprocess::named_mutex named_mtx(boost::interprocess::open_or_create, "mtx");
	boost::interprocess::named_condition named_cnd(boost::interprocess::open_or_create, "cnd");
	boost::interprocess::scoped_lock lock(named_mtx);
	while (*i < 10)
	{
		if (*i % 2 == 0)
		{
			++(*i);
			named_cnd.notify_all();
			named_cnd.wait(lock);
		}
		else
		{
			std::cout << *i << std::endl;
			++(*i);
			named_cnd.notify_all();
			named_cnd.wait(lock);
		}
	}
	named_cnd.notify_all();
	boost::interprocess::shared_memory_object::remove("shm");
	boost::interprocess::named_mutex::remove("mtx");
	boost::interprocess::named_condition::remove("cnd");
*/

	try
	{
		boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024);
		int *i = managed_shm.find_or_construct<int>("Integer")(0);
		boost::interprocess::interprocess_mutex *mtx = managed_shm.find_or_construct<boost::interprocess::interprocess_mutex>("mtx")();
		boost::interprocess::interprocess_condition *cnd = managed_shm.find_or_construct<boost::interprocess::interprocess_condition>("cnd")();
		boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(*mtx);
		while (*i < 10)
		{
			if (*i % 2 == 0)
			{
				++(*i);
				cnd->notify_all();
				cnd->wait(lock);
			}
			else
			{
				std::cout << *i << std::endl;
				++(*i);
				cnd->notify_all();
				cnd->wait(lock);
			}
		}
		cnd->notify_all();
	}
	catch (...)
	{
	}
	boost::interprocess::shared_memory_object::remove("shm");

	system("pause");
	return 0;
}

你可能感兴趣的:(boost教程)