2015-04-04 13 views
8

Birkaç gün önce Qt5 kullanmaya başladım. Uygulamam için bir logger'a ihtiyacım vardı ve qDebug'u kullanmaya karar verdim, ancak bir dosyada günlükleri olması için "yeniden yönlendirilmiş" olması gerekiyor.Qt5: Bir dosyada oturum açmak için qDebug() nasıl kullanılır, çok parçalı bir uygulama

Bunu yapmak için qInstallMessageHandler kullanmıştım ve aşağıda gösterildiği gibi kendi işleyicimi yazdım (burada diğer insanlardan ilham).

Çalışıyor gibi görünüyor, ama ben bir guru olmadığım için şunu sormam gerekiyor: Bunu çok-parçalı bir uygulamada kullanmak doğru mudur?

Ayrıca, çok parçalı bir uygulamasında kullanımda/güvenli ise, bir şekilde geliştirilebilir mi?
Teşekkürler!

void MessageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg) 
{ 
    mutex.lock(); 

    QDateTime dateTime(QDateTime::currentDateTime()); 

    QString timeStr(dateTime.toString("dd-MM-yyyy HH:mm:ss:zzz")); 
    QString contextString(QString("(%1, %2)").arg(context.file).arg(context.line)); 

    QFile outFile("file.log"); 
    outFile.open(QIODevice::WriteOnly | QIODevice::Append); 

    QTextStream stream(&outFile); 
    stream << timeStr << " " << contextString << ": " << msg << endl; 

    mutex.unlock(); 
} 
+0

Değişkeniniz 'mutex' türünüzde? –

+0

statik QMutex muteks; // global variable –

+0

Hangi işletim sistemini geliştiriyorsunuz? –

cevap

1

Yaklaşımınız basit ve temiz görünüyor. Onu öyle tutardım.

Geliştirebileceğiniz bir şey var: Uygulamayı başlatırken dosyayı yalnızca bir kez açın ve uygulamayı kapattığınızda kapatın. Bir dosyayı açmak pahalı bir işlemdir.

Aynı açık dosyaya birden çok iş parçacığından yazabilirsiniz, çünkü muteksiniz aynı anda yalnızca bir iş parçacığının yazmasını sağlar.

+0

Simon, zaman ayırdığınız için ve tavsiyeniz için teşekkürler! Dosyayı açılışta yalnızca bir kez açabilirim, fakat (çok yakın bir gelecekte) dosya adını "dd-mm-yyy.log" gibi bir dosyaya "file.log" dan değiştirmeyi planlıyorum. ne demek istediğimi bildiğinizden emin olun :) Yani, uygulama başlangıcında günlük dosyasını açmak imkansız olurdu ... Bu sorun için herhangi bir fikir/çözüm var mı? Şimdiden teşekkürler! –

+0

@groenhen Uygulamanın bir günden fazla çalışmasını bekliyor musunuz? –

+0

Evet, durmadan çalışacak (en azından umarım:) ...) –

2

Her yerde qDebug parçacığı güvenli olduğunu Qt belgelerinde bulamıyorum. Bu yüzden, aynı anda birden fazla iş parçacığı olarak adlandırmak güvenli değildir ve gerçekten bir kilitleme mekanizması kullanmazsanız karma çıkışla karşılaşırsınız.

kuvvetle Qt belgelerine tarafından önerilen gibi QMutexLocker kullandığınız takdirde kilitleme yaklaşım daha iyi olurdu:

void MessageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg) 
{ 
    QMutexLocker locker(&mutex); 
    ... 
} 

ikinci bir yaklaşım günlüğü yazmak için yuvaya sahiptir işçi sınıfını sağlamaktır. Daha sonra yeni bir iş parçacığındaki bir örneğiniz olabilir ve bağlantı türüyle QMetaObject::invokeMethod kullanarak ileti işleyicisindeki yuvaları çağırabilirsiniz. Bu şekilde, her bir iş parçacığındaki her çağrı kuyruğa alınacak ve iş parçacığı içinde işlenecektir ve işin tamamı ayrı bir iş parçacığında yapıldığından muhtemelen daha iyi bir performans gösterecektir.

+1

Ama AFAIK, "QMutexLocker dolabı (& mutex);" mutex.lock() ile aynı işi yapar, mutex.unlock() ile takip eder, tek fark, eğer bu fonksiyon/metot birden fazla çıkış/geri dönüş noktasına sahip olduğunda/endişelenmenize gerek olmamasıdır. Dolap, bir otomatik değişken olduğu için muteks çıkışta otomatik olarak açılır. Saygılarımızla, SG. –

+0

BTW: Peki ya "hız açısından" ...? Hangisi daha hızlı, mutex lock/unlock() veya QMutexLocker mekanizması? –

+0

Hız açısından farklılık gösterip göstermediklerini bilmiyorum. Ancak ikinci bir yaklaşım, çalışan bir iş parçacığına sahip olmak ve orada operasyon yapmaktır. Düzenlenen cevaba bakınız. – Nejat

İlgili konular