Реализация автосохранения без сбоев
Вопрос
Я взломал код для Xournal, чтобы добавить функцию автоматического сохранения.Моя первоначальная реализация была очень глупой:примерно каждые 60 секунд делайте сохранение.Эта функция якобы работает.
Однако, протестировав его некоторое время, я заметил, что при запуске функции автоматического сохранения приложение временно зависает, что довольно раздражает, если вы находитесь в середине штриха пера.Я пытаюсь понять, как это исправить.
Одна из возможностей, о которой я подумал, - это автосохранение, позволяющее проверить, касается ли перо экрана перед автосохранением;если к нему прикоснулись, добавьте одноразовый обратный вызов, запланированный на секунду после поднятия пера.(если произойдет то же самое, повторите).Другой возможностью было бы оптимизировать функцию сохранения в достаточной степени, чтобы не было пробелов (кажется маловероятным).
У кого-нибудь есть какие-либо предложения по этому поводу?Xournal использует инструментарий Gnome / GTK и написан на C.
Обновить: Я реализовал логику защиты от сглаживания, и я очень доволен результирующей детализацией и производительностью автосохранения.Один из тех случаев, когда потоки (к счастью) не нужны!Спасибо всем за ваши предложения.
Решение
Если пользовательский интерфейс зависает в течение какого-либо заметного периода времени, вероятно, стоит использовать отдельный поток. Если единственная причина, по которой вы замечаете зависание пользовательского интерфейса, заключается в том, что вы пишете в то время, а прерывание очень короткое, тогда ваш метод может работать. Ваше исправление, вероятно, намного проще, чем создание другого потока, поэтому попробуйте сначала.
Если вы в конечном итоге используете потоки, используйте g_threads вместо pthreads, поскольку вы используете GTK +. Они будут более портативными.
Другие советы
Хотя я бы согласился, что использование потоков - это "правильный" ответ в текстовом поле, это не всегда так, как вы должны что-то делать.Многопоточность, как правило, вызывает массу проблем, если вы не будете осторожны - основной из них здесь, вероятно, является блокировка доступа к данным во время автосохранения.Затем, если основной поток переходит в режим ожидания для доступа к данным, вы возвращаетесь к тому, с чего начали.Итак, затем вы создаете очередь ожидающих изменений или что-то в этом роде и теряете представление о том, что происходит.В зависимости от того, насколько сложны базовые структуры данных, создание копии также может заморозить основной поток.
В любом случае дело в том, что я бы попробовал ваш первый вариант.Это быстро, просто и по существу, и я не понимаю, почему это не сработает.
(Примечание:Я не заглядывал под капот Xournal, так что отнеситесь к этому со всей серьезностью.Или солонку.Или что-то в этом роде)
Можете ли вы перенести функцию автосохранения в отдельный поток? Запустив второй поток, вы сможете запустить сохранение параллельно с графическим интерфейсом и избежать появления окна зависания.
У меня очень мало опыта работы с c, но я бы подумал, что этот сайт может помочь.
В прошлом у меня была похожая ситуация, и вот как я ее решил (.Net):
<Ол>Единственный недостаток, который мы видели на самом деле, это то, что кто-то убивал приложение до вызова обработчика событий и терял 1 минуту работы.
Как насчет этого?
Используйте идею обратного вызова, но она должна запускаться каждые 10 входов в дополнение к каждые 60 секунд. При использовании автосохранения, основанного на времени, существует проблема, заключающаяся в том, что количество потерянных материалов пропорционально скорости работы пользователя.
Если вы хотите пойти еще дальше, сохраните частичный журнал отмены на диск после каждого изменения в дополнение к полному сохранению. Таким образом, худшее, что может случиться при сбое, - это потерять последний такт ввода.
Моя задача - использовать поток hipervisor, сравнивающий с помощью некоторого алгоритма хеширования содержимое файла каждые N секунд при изменении, затем уведомлять родительский поток и вызывать функцию автосохранения.