Блоки GCD в частной очереди перестают выполняться с большими базами данных SQLite3

0

У меня есть последовательная очередь, созданная следующим образом:

self.myQueue = dispatch_queue_create("com.myDomain.myQueue", DISPATCH_QUEUE_SERIAL);

У меня есть база данных sqlite3 для хранения моих данных. Вместо того, чтобы каждый раз записывать эти данные, каждый раз, когда я получаю кусок данных, я храню его в буфере - в данном случае - на "основе" на основе CPP на нижнем уровне.

Я добавляю блоки в свою приватную очередь для записи в буфер. Для этого я использую dispatch_async(). После предопределенного интервала времени я передаю данные в БД из буфера.

Когда БД находятся ниже 5 МБ, все работает так, как ожидалось, - все данные поступают, каждый записывается в буфер, по истечении интервала времени данные передаются в БД из буфера.

Когда размер БД увеличивается до более 5 МБ (приблизительно), блоки в очереди, похоже, не выполняются до временного интервала для передачи данных в БД. Когда это время будет сделано, одна запись будет записана в буфер. В следующий раз истекает интервал времени, данные передаются в БД, и снова в буфер записывается только одна запись - на этот раз другая запись, которая находится в последовательности, я ожидаю, что записи войдут. Кажется, что каждый блок выполняется только после того, как я написал в БД, который происходит только каждый раз, когда я нахожусь на определенном временном интервале.

Примечание. Я проверил, что эти блоки выполняются, выполняются чисто - без ошибок.

Я не могу понять ссылку здесь между размером БД и невыполнением (если есть такое слово) блоков в частной очереди.

Связана ли ширина его частной очереди с ней? Или проблема памяти? Я бы сказал, размер БД, но кажется, что каждый раз-интервальные блоки выполняются правильно. Кроме того, я бы сказал, DB размер напрямую, но я не могу писать в буфер.

Любые мысли, чтобы дать мне направление ИЛИ, это проблема ОС вне моего контроля?

  • 0
    Как выглядит ваш коммит-блок?
Теги:
sqlite3
grand-central-dispatch
ios6

1 ответ

1
Лучший ответ

Не совсем понятно, как вы его настроили: похоже, у вас есть вектор, который защищен для одновременного доступа с использованием последовательной очереди. Похоже, вы также выполняете периодическую операцию с базой данных в одной очереди. Поскольку это последовательная очередь, если операции с базой данных начинают занимать больше времени и дольше, другие операции будут выполнять резервное копирование за операцией базы данных. Я бы рекомендовал использовать очередь только для примитивных операций над vector и использовать вторую очередь для управления операциями с базой данных. Это может выглядеть примерно так:

using namespace std;

dispatch_queue_t vectorQueue = NULL;
dispatch_queue_t dbQueue = NULL;
dispatch_source_t timer = NULL;
vector<whatever>* dbRecords = NULL;

void init()
{
    dbRecords = new vector<whatever>();
    vectorQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    dbQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dbQueue);
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, NSEC_PER_SEC * 60, NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        __block vector<whatever>* toCommit = NULL;
        dispatch_sync(vectorQueue, ^{
            if (dbRecords->size())
            {
                toCommit = new vector<whatever>(*dbRecords);
                dbRecords->clear();
            }
        });

        if (toCommit)
        {
            // Commit the records using your db code...

            delete toCommit;
        }
    });
    dispatch_resume(timer);
}

void enqueueRecord(whatever record)
{
    dispatch_async(vectorQueue, ^{
        dbRecords->push_back(record);
    });
}

Таким образом, входящие блоки записи не резервируются, ожидая операции с базой данных. Единственными блоками, выполняемыми в vectorQueue являются операции с общим вектором. Когда его время для фиксации на db, вы копируете записи из общего вектора в частную копию, очищаете общий вектор и отправляете личную копию на dbQueue должна быть зафиксирована.

  • 0
    Хорошо. Но не вызовет ли это проблемы с фиксацией БД? Я имею в виду, если я удалил записи из вектора, в то время как записи все еще добавляются к нему из векторной очереди?
  • 0
    Какую проблему вы думаете, это может вызвать? В этом примере, когда dbQueue читает вектор, он делает это с помощью dispatch_sync для vectorQueue .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню