5

Uzaktaki bir makineden ileti alacak ve iletileri diskteki bir dosyaya yazması gereken bir program oluşturuyorum. Bulduğum zorluk, bu programın amacının mesajların alındığı kütüphanenin performansını test etmek olduğu ve bu nedenle mesajların diske yazılmasının kütüphanenin performansını etkilemediğinden emin olmam gerektiğidir. . Kütüphane, mesajları bir geri çağırma işleviyle programa iletir. Diğer bir zorluk ise çözümün platformdan bağımsız olması gerektiğidir.Platform bağımsız asenkron yazım nasıl yapılır?

Hangi seçeneklerim var?

benim aklıma şu: boost:asio kullanarak

  • dosyaya yazmak için, ancak dosyaya uyumsuz yazma bu kütüphanenin, Windows belirli bir bölgesinde olduğu (this belgelerine bakın) görünüyor - bu yüzden bu olamaz Kullanılmış.
  • Bir ileti sırası oluşturmak için boost::interprocess'u kullanmak ancak this documentation, iletilerin gönderilebileceği 3 yöntemin bulunduğunu ve tüm yöntemlerin program kuyruğu doluysa (örtülü veya değil) programın engellenmesini gerektirdiğini belirtir; risk.
  • std::deque<MESSAGES> geri çağırma işlevinden deque öğesine basıp, dosyaya (ayrı bir iş parçacığında) yazarken iletileri dışarı çıkartır, ancak STL kapsayıcıları not guaranteed to be thread-safe'dir. İğneyi devirip kilitleyebilirim, ama dehşete kapılıyorum ama birbirini takip eden mesajlar arasında 47 mikro saniyeden bahsediyoruz, böylece kilitleri tamamen önlemek istiyorum.

Olası çözümler hakkında başka fikri olan var mı?

+0

Hangi mesajlar arasında 47 mikrogram var? Uzak makine kadansı mı? –

cevap

2

STL konteynırlar vida dişi olabilirler, ancak farklı zamanlarda farklı zamanlarda kullanılamayan bir yere vurmadım. Sahipliği başka bir konuya geçirmek güvenli görünüyor. Ben birkaç kez izleyen kullandık, bu yüzden çalıştığını biliyorum

:

  • bir std :: dizisine bir gösterici oluşturun.
  • Vektör işaretçisini korumak için bir muteks kilidi oluşturun.
  • std :: vector oluşturmak için yeni [] kullanın ve bunun için büyük bir boyut() ayırın. Alıcı thread

: kuyruğuna bir öğe ekleyerek her

  • muteks'i kilitleyin. Bu kısa bir kilit olmalı.
  • Sıra öğesi ekleyin.
  • Kilidi bırakın.
  • Bir koşul değişkenini bildirmeyi düşünüyorsanız. Bazen yapmam: tasarımına bağlı. Hacim çok yüksekse ve alma tarafında duraklama yoksa, durumu ve anketi atlayın.

    • Git yoklama veya koşul değişkeni bekleyen tarafından yapılacak iş aramak:
    • Lock kuyruk muteks tüketici parçacığı (Disk yazar) Açık

    .

  • Kuyruk uzunluğuna bakın.
  • Kuyrukta iş varsa, iş parçacığında tüketici işaretçisini bir değişkene atayın.
  • Yeni bir sıra vektörü oluşturmak ve sıra işaretçisine atamak için yeni [] ve reserve() kullanın.
  • Muteks kilidini açın.
  • Git ve öğelerinizi diske yaz.
  • [] kullanılan sıra vektörünü silin.

Şimdi, sorununuza bağlı olarak, engellenmenin bir yoluna ihtiyacınız olabilir. Örneğin, programımın birinde kuyruk uzunluğu 100.000 maddeye ulaşırsa, üretme iş parçacığı sadece 1 saniyelik uykular yapmaya ve çok fazla şikayet etmeye başlar. Olmaması gereken şeylerden biri, yine de öyle, yani bunu düşünmelisin. Herhangi bir sınırlama olmaksızın, sadece makinedeki tüm belleği kullanacak ve bir istisna ile çarpacak, OOM tarafından öldürülecek ya da sadece bir takas fırtınasında durma noktasına gelecektir.

+0

Diğer cevabı okudum. Öğe başına kilitleme çok pahalıysa, bu gereksinime de uyarlayabilirsiniz. Sadece vektör işaretçilerinin bir vektörünü tutun ve yazmayı bitirdiğinizde sadece bir vektör ekleyin. –

+0

Başka bir not: Bu tasarım, mutekslerin hiçbir çekişme olmadığı zaman çok düşük maliyetli olan futexleri kullandığı Linux'ta benim için çok iyi çalıştı. Ve CriticalSection kullanarak BSD veya Windows üzerinde kötü değil. Ancak çok çok platformlu olmak istediğiniz için yuvalanmış konteyner kilitleme gerçekten en iyi olabilir. –

2

boost :: iş parçacığı platformdan bağımsızdır, bu nedenle engelleme yazmalarını yapmak için bir iş parçacığı oluşturmayı kullanabilmeniz gerekir.

std::deque<std::deque<MESSAGES> > 

Sonra sadece üst düzey deque kilitlemek, aşağıdaki gibi iç içe kaplar oluşturarak çift tamponlama tekniği bir değişiklik kullanabilir haznesini mesajı ana iş parçacığı yerleştirilir her zaman kilitlemek gerek önlemek için Mesajlarla dolu bir deque eklenmeye hazır. Yazma iş parçacığı, sadece, yazılacak mesajlarla dolu bir deque'i çıkarmak için üst düzey deque'i kilitlerdi.

İlgili konular