Implementação de gravação automática w / o rompimento
Pergunta
Eu tenho sido hacking sobre o código para Xournal para adicionar auto-save funcionalidade. Minha implementação inicial era muito idiota: a cada 60 ou assim segundos, fazer a defesa. O recurso ostensivamente funciona.
No entanto, depois de testá-lo por um tempo, tenho notado que quando auto-save é executado, o aplicativo congela temporariamente, o que é muito chato se você estiver no meio de um traço de caneta. Eu estou tentando descobrir como consertar isso.
Uma possibilidade que eu pensava-se de é para gravação automática para verificar se há ou não a caneta está tocando a tela antes de a gravação automática; se for tocada, anexar uma única vez callback prevista para um segundo após a caneta é levantada. (Se acontece a mesma coisa, repetir). Outra possibilidade seria a de otimizar a função de economia suficientemente de tal forma que não há diferença (parece improvável).
Alguém tem alguma sugestão sobre isso? Xournal utiliza o kit de ferramentas Gnome / GTK, e é escrito em C.
Update: eu implementei a lógica anti-clobber, e eu estou muito feliz com a granularidade de gravação automática resultante e desempenho. Uma dessas vezes tópicos são (felizmente) não é necessário! Obrigado a todos por suas sugestões.
Solução
Se a interface do usuário congela por um período considerável de tempo, um segmento separado é provavelmente o caminho a percorrer. Se a única razão que você está percebendo o congelamento UI é porque você acontecer a ser escrito no momento ea interrupção só é muito breve, então o seu método de trabalho poder. Sua correção é provavelmente a maneira mais fácil do que criar outro segmento, de modo a tentar que o primeiro.
Se você acabar usando threads, ir com g_threads em vez de pthreads desde que você está usando GTK +. Eles vão ser mais portátil.
Outras dicas
Enquanto eu concordaria usando threads é uma resposta caixa de texto "correta", nem sempre é a maneira que você tem que fazer as coisas. Multithreading tende a trazer toneladas de problemas se você não tiver cuidado - a principal delas aqui provavelmente a ser bloqueio o acesso aos dados durante a gravação automática. Então, se o thread principal entra uma espera para acessar os dados, você está de volta à direita onde você começou. Então você criar uma fila de alterações pendentes ou algo assim, e você perder a noção do que está acontecendo. Dependendo do quão complexo estruturas de dados subjacentes são, fazendo uma cópia também pode congelar a thread principal.
De qualquer forma ponto ser, gostaria de tentar sua primeira opção. É rápido, simples e direto ao ponto, e eu não vejo por que ele não iria funcionar.
(Nota:.. Eu não olhei sob a capa de Xournal isso tome isso com um grão de sal ou um saleiro ou algo assim)
Você pode empurrar a funcionalidade de gravação automática para um segmento separado? Ao executar em um segundo segmento que você seria capaz de executar o salvamento em paralelo com o gui e evitaria a janela congelamento.
Eu tenho muito pouca experiência com c, mas eu acho neste site poderia ajudar.
Eu tive uma situação semelhante no passado, e aqui é a forma como eu resolver aquilo (.Net):
- Contador fundo carrapatos em x segundos de intervalo
- No carrapato, desativar o timer e manipular o evento apropriado.
- No manipulador de eventos, salvar e ativar o timer.
A única falha que nós vimos realmente acontecer era alguém matar o aplicativo antes de o manipulador de eventos é chamado e perder valor do trabalho a 1 minuto.
Como sobre isso?
Use a idéia de retorno de chamada, mas tê-lo executado a cada 10 entradas, além de a cada 60 segundos. Com uma gravação automática com base no tempo, há um problema que a quantidade de material que se perde é proporcional ao quão rápido o usuário pode trabalhar.
Se você quiser ir um passo mais longe, tem que salvar um log de desfazer parcial para o disco depois de cada mudança, além da completa save. Dessa forma, a pior coisa que pode acontecer a partir de um acidente está a perder o último golpe de entrada.
O meu foco é usar um fio hipervisor comparando através de algum algoritmo de hash do conteúdo do arquivo a cada N segundos em evento de alteração, em seguida, notificar ao segmento pai e retorno de chamada a função de gravação automática.