如何在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; } 

它也适用于并发环境。