如何在C中创建Singleton?
在C中创建单例的最佳方法是什么? 并发解决方案会很好。
我知道C不是你用于单身人士的第一种语言。
首先,C不适合OO编程。 如果你这样做,你会一直在战斗。 其次,单例只是具有一些封装的静态变量。 所以你可以使用静态全局变量。 然而,全局变量通常具有与其相关的太多弊病。 否则你可以使用函数本地静态变量,如下所示:
int *SingletonInt() { static int instance = 42; return &instance; }
或更聪明的宏:
#define SINGLETON(t, inst, init) t* Singleton_##t() { \ static t inst = init; \ return &inst; \ } #include /* actual definition */ SINGLETON(float, finst, 4.2); int main() { printf("%f\n", *(Singleton_float())); return 0; }
最后,请记住,单身人士大多被滥用。 很难让它们正确,特别是在multithreading环境下……
你不需要。 C已经有全局变量,所以你不需要一个解决方法来模拟它们。
它几乎和C ++版本一样。 只需要一个返回实例指针的函数。 它可以是函数内部的静态变量。 根据平台,使用临界区或pthread互斥体包裹function体。
#include struct A { int a; int b; }; struct A* getObject() { static struct A *instance = NULL; // do lock here if(instance == NULL) { instance = malloc(sizeof(*instance)); instance->a = 1; instance->b = 2; } // do unlock return instance; };
请注意,您还需要一个function来释放单例。 特别是如果它抓取在进程退出时未自动释放的任何系统资源。
编辑:我的回答假设你正在创建的单身人士有点复杂,并且有一个多步创建过程。 如果它只是静态数据,请像其他人建议的那样使用全局数据。
C中的单身人士会非常奇怪。 。 。 我从未见过一个看起来特别优雅的“面向对象的C”的例子。 如果可能,请考虑使用C ++。 C ++允许您选择要使用的function,许多人只是将它用作“更好的C”。
下面是一个非常典型的无锁一次性初始化模式。 如果前一个为null,则InterlockCompareExchangePtr以新的值primefaces交换。 这可以保护多个线程同时尝试创建单例,只有一个会赢。 其他人将删除他们新创建的对象。
MyObj* g_singleton; // MyObj is some struct. MyObj* GetMyObj() { MyObj* singleton; if (g_singleton == NULL) { singleton = CreateNewObj(); // Only swap if the existing value is null. If not on Windows, // use whatever compare and swap your platform provides. if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL) { DeleteObj(singleton); } } return g_singleton; } DoSomethingWithSingleton(GetMyObj());
这是另一个视角:C程序中的每个文件实际上都是一个单例类,它在运行时自动实例化,不能被子类化。
- 全局静态变量是您的私有类成员。
- 全局非静态是公共的(只是在某些头文件中使用
extern
声明它们)。 - 静态函数是私有方法
- 非静态函数是公共函数。
给所有东西一个正确的前缀,现在你可以使用my_singleton_method()
代替my_singleton.method()
。
如果您的单例是复杂的,您可以编写一个generate_singleton()
方法来在使用之前对其进行初始化,但是您需要确保所有其他公共方法检查它是否被调用,否则出错。
做就是了
void * getSingleTon() { static Class object = (Class *)malloc( sizeof( Class ) ); return &object; }
它也适用于并发环境。