我得到了一个类,实例化时需要获得一些唯一的ids才能工作。最初,我认为使用一个分配和递增的静态函数。我不需要他们是连续的,唯一的。
class A {
int id_1;
int id_2;
int id_3;
public:
static int last_id=0;
static int get_id(){ return A::last_id++; }
...
A(){ id_1 = A::get_id(); id_2 = A::get_id(); id_3 = A::get_id(); }
};现在,我在考虑如何进行多线程。我认为静态函数将是一个瓶颈,因为我在开始时正在构建这些对象的几十万个实例。在程序结束之前,我不会销毁任何实例,所以在初始化之后,它们是固定的。无论如何,它们不是在编译时计算的,因为数量取决于命令行参数。
我正在考虑的另一种方法是使用内存地址,它们至少在一台计算机中是独一无二的。
类似于:
class A {
int* id_1;
int* id_2;
int* id_3;
public:
static int last_id=0;
static int get_id(){ return A::last_id++; }
...
A(){ id_1 = new int(0); id_2 = new int(0); id_3 = new int(0); }
~A() { delete id_1; delete id_2; delete id_3(); }
};然后,我会将标识符读取为指针的地址。
问:使用这样的指针有意义吗?
发布于 2014-07-31 00:12:54
我以前在C中使用过类似于以下内容的快速攻击--当我需要一些唯一的值时,这些值仅在进程的生命周期内是唯一的。
constants.h
extern const void * id_1;
extern const void * id_2;constants.c
const void * id_1 = &id_1;
const void * id_2 = &id_2;不用担心清理等,因为他们是外向型的全球。
在C++中,对于类实例,您可以使用相同的想法,但将其本地化到实例:
class A {
void* id_1;
void* id_2;
void* id_3;
public:
A(){ id_1 = &id_1; id_2 = &id_2; id_3 = &id_3; }
};请注意,只有在实例存在时,ids才是唯一的--但您已经说过,它们只在应用程序退出时被销毁--所以您应该没事。
Note:我确实认为这是一种黑客行为,而使用C++11s std::atomic,上面的Travis提供的解决方案是简单的,而且更健壮。但是,如果没有C++11,实现原子库或添加原子库就会很麻烦。
发布于 2014-07-31 00:25:38
我刚刚想出了这个,所以我不知道它是否安全!根据需要向类添加任意数量的ID成员。
struct ID
{
uintptr_t GetID() const
{
return reinterpret_cast<uintptr_t>(this);
}
};发布于 2014-07-31 00:32:04
id的唯一性意味着一个瓶颈,无论它是通过使计数器线程安全,还是依赖线程安全新的。
最好将last_id设置为atomic<int>,并使用运算符++将其作为原子操作进行增量。我相信这将比new为了分配虚拟int而必须做的所有堆管理工作更有效率。
如果这将成为一个真正的瓶颈,您可以使用一种稍微不同的方法,使用每个线程本地的id生成器,并将本地(即没有争用) id与线程id (只要线程保持可连接性,this_thread::get_id()是唯一的)组合在一起,以便使唯一的id跨越所有线程。
这方面的一个变体是按照前面的建议使用静态原子int,但同时分配多个in的块(并在每个线程中本地管理缓存的in)。
https://stackoverflow.com/questions/25048900
复制相似问题