Как создать Singleton в C?

Используйте while для чтения целых строк, а не для итерации по словам , полученным в результате подстановки команд.

while IFS= read -r obj; do
    ...
done < <(jq -c '.[]' posts.json)
25
задан nbro 8 April 2017 в 00:49
поделиться

4 ответа

Во-первых, C не подходит для программирования ОО. Вы бы боролись всю дорогу, если бы вы сделали. Во-вторых, синглтоны - это просто статические переменные с некоторой инкапсуляцией. Таким образом, вы можете использовать статическую глобальную переменную. Однако с глобальными переменными обычно связано слишком много проблем. В противном случае вы можете использовать локальную статическую переменную функции, например:

 int *SingletonInt() {
     static int instance = 42;
     return &instance;
 }

или более умный макрос:

#define SINGLETON(t, inst, init) t* Singleton_##t() { \
                 static t inst = init;               \
                 return &inst;                       \
                }

#include <stdio.h>  

/* actual definition */
SINGLETON(float, finst, 4.2);

int main() {
    printf("%f\n", *(Singleton_float()));
    return 0;
}

И, наконец, помните, что синглтонами в основном злоупотребляют. Трудно понять их правильно, особенно в многопоточных средах ...

30
ответ дан 28 November 2019 в 18:12
поделиться

Это почти то же самое, что и версия C ++. Просто есть функция, которая возвращает указатель экземпляра. Это может быть статическая переменная внутри функции. Оберните тело функции критическим разделом или мьютексом pthread, в зависимости от платформы.

#include <stdlib.h>

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;
};

Обратите внимание, что вам также понадобится функция для освобождения синглтона. Особенно, если он захватывает любые системные ресурсы, которые не освобождаются автоматически при выходе из процесса.

14
ответ дан 28 November 2019 в 18:12
поделиться

Тебе не нужно. В C уже есть глобальные переменные, поэтому вам не требуется обходной путь для их моделирования.

19
ответ дан 28 November 2019 в 18:12
поделиться

РЕДАКТИРОВАТЬ: Мой ответ предполагает, что создаваемый вами синглтон является довольно сложным и имеет многоэтапный процесс создания. Если это просто статические данные, переходите к глобальным, как предлагали другие.

Синглтон в C будет очень странным. , , Я никогда не видел пример «объектно-ориентированного C», который выглядел бы особенно элегантно. Если возможно, подумайте об использовании C ++. C ++ позволяет вам выбирать, какие функции вы хотите использовать, и многие люди просто используют его как «лучший C».

Ниже приведен довольно типичный шаблон для одноразовой инициализации без блокировки. InterlockCompareExchangePtr атомарно меняет новое значение, если предыдущее значение равно нулю. Это защищает, если несколько потоков пытаются создать синглтон одновременно, победит только один. Остальные будут удалять только что созданный объект.

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());
5
ответ дан 28 November 2019 в 18:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: