concurrent_has_map是TBB中设计的符合stl规范的防止并发访问的hash table模板类,主要使用格式为:concurrent_hash_map<key, T, hashcompare>,其中 key和T是一键值对,而hashcompare则定义了hash值的产生和keys的比较。本文主要介绍该模板类的使用(下面是实现一个随机生成字符串数组存储的程序):

        如下是一个自定义hashcompare结构体,该结构体定义了hash值的产生函数及两个关键key值的比较:

struct MyHashCompare
{
	static size_t hash(const string & x)
	{
		size_t h = 0;
		for ( const char* s= x.c_str(); *s; ++s)
		{
			h = (h*17)^*s;
		}

		return h;
	}

	static bool equal( const string & x, const string & y)
	{
		return x==y;
	}
};

typedef concurrent_hash_map<string, int, MyHashCompare> StringTable;

      随机生成字符串函数如下(生成a-Z之间的字符,然后组成字符串):

string generateRandomString()
{
	char str[9];	
	char c1 = rand()%26 + 65;
	char c2 = rand()%26 + 65;
	char c3 = rand()%26 + 65;
	char c4 = rand()%26 + 65;

	char c5 = rand()%26 + 65;
	char c6 = rand()%26 + 65;
	char c7 = rand()%26 + 65;
	char c8 = rand()%26 + 65;

	sprintf(str, "%c%c%c%c%c%c%c%c",c1,c2,c3,c4,c5,c6,c7,c8);
	return string(str);
}
        用StringTable进行输入数据处理的结构体:

struct Tally
{
	StringTable& m_table;

	Tally(StringTable & table_):m_table(table_){}

	void operator()(const blocked_range<string*>range) const
	{
		for ( string* p = range.begin(); p!=range.end(); ++p)
		{
			StringTable::accessor a;
			m_table.insert(a, *p);
			a->second += 1;
		}
	}
};
        测试例子:

void concurrent_hash_map_test()
{
	tick_count t0 = tick_count::now();

	const size_t N = 100000;

	string *Data = new string[N];

	for ( int i=0; i<N; ++i)
	{
		Data [i] = generateRandomString();
	}

	StringTable table;
	parallel_for(blocked_range<string*>(Data, Data+N, 100), Tally(table));

	//	printf("Table.size=%d\n", table.size());

	int count = 0;

	for ( StringTable::iterator i= table.begin(); i!=table.end(); ++i)
	{
		printf("size=%d,%s %d\n",table.size(), i->first.c_str(), i->second);
		if ( i->second ==1 )
		{
			count ++;
		}
	}

	printf("出现一次的个数:%d\n", count);

	tick_count t1 = tick_count::now();

	printf("程序执行时间为:%g seconds\n", (t1-t0).seconds());

	delete[]Data;

	//	string str = generateRandomString();
	//	printf("%s", str.c_str());	
}
          直接在main中调用该函数就可以运行了。在本例中,没有对concurrent_hash_map的结构或源码进行剖析,熟悉stl库的童鞋可以很轻松的应用该类,想了解更多的资料,可以查阅tbb源码或参考inel threading building blocks outfitting c++ for multi-core processor parallelisn。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐