Bir oyun projesi için bazı çok iş parçacıklı kodlarla çalışıyorum ve aynı anda iletileri ayıklamak için cout'u kullanan iki iş parçacığı tarafından oluşturulan stdout kusmayla sıralamada biraz yoruldum. Biraz araştırma yaptım ve bir şeyle gelmeden önce bir iki saat boyunca bir duvara baktım. Aşağıdaki kod, zaman tutma ve iş parçacığı için SFML kullanır. SFML muteksleri sadece pencerelerde kritik bölümlere sarılır.İplik güvenli diş tekniği. Bir şey mi eksik?
Üstbilgi:
#include <SFML\System.hpp>
#include <iostream>
class OutputStreamHack
{
public:
OutputStreamHack();
~OutputStreamHack();
ostream& outputHijack(ostream &os);
private:
sf::Clock myRunTime;
sf::Mutex myMutex;
};
static OutputStream OUTHACK;
ostream& operator<<(ostream& os, const OutputStreamHack& inputValue);
Uygulama:
#include <SFML\System.hpp>
#include <iostream>
#include "OutputStreamHack.h"
using namespace std;
OutputStreamHack::OutputStreamHack()
{
myMutex.Unlock();
myRunTime.Reset();
}
OutputStreamHack::~OutputStreamHack()
{
myMutex.Unlock();
myRunTime.Reset();
}
ostream& OutputStreamHack::outputHijack(ostream &os)
{
sf::Lock lock(myMutex);
os<<"<"<<myRunTime.GetElapsedTime()<<","<<GetCurrentThreadId()<<"> "<<flush;
return os;
}
ostream& operator<<(ostream& os, const OutputStreamHack& inputValue)
{
OUTHACK.outputHijack(os);
return os;
}
Kullanım:
cout<<OUTHACK<<val1<<val2<<val3....<<endl;
Ok, bu çalışma şekli kilitleyerek iplik güvenlik getirir bir aşırı ekleme operatörü olan Statik bir nesnede bir yineleyici, ardından arabelleği temizleme. Eğer süreci doğru bir şekilde anladım (çoğunlukla kendimi öğreten bir programcıyım), yerleştirme zincirinin elemanlarını uçtan başlayarak en başından sonuna kadar geçirir ve her bir elemanın akışa eklenmesi için bir aşağı akış değişkenini zincirden geçirir. OUTHACK öğesine ulaştığında, aşırı yüklenen operatör çağrılır, muteks kilitlenir ve akış boşaltılır.
Doğrulama için çıktıya zaman/iş parçacığı kimliği hata ayıklama bilgisi ekledim. Şimdiye kadar, testlerim bu yöntemin çalıştığını gösteriyor. Birden fazla argümanla cout'u çarptıran birkaç konu var ve her şey doğru sırada çıkıyor.
Bu konuyu araştırırken okuduklarımdan beri, diş ipinde emniyetin olmaması, insanların dişli programlamaya girerken karşılaştıkları oldukça yaygın bir sorun gibi görünüyor. Anlamaya çalıştığım teknik, kullanmakta olduğum teknik sorun için basit bir çözüm mü yoksa akıllı olduğumu düşünürken önemli bir şey eksik olduğunu düşünmekteyim.
Deneyimlerime göre, programlamayı tanımlamak için kullanıldığında akıllı sözcük, gecikmiş acı için sadece bir kod kelimesidir. Burada bir şeye ya da etrafta dolanan hackerları kovalamak mı?
Teşekkürler!
Çalışması gerçektir. Sadece zaman ve iş parçacığının kimliği, muteks tarafından korunur. OUTHACK ve "val1" arasında başka bir iş parçacığı gizlice almak mümkün. –
İlk önce bir "ostringstream" 'e yazmayı, ardından içeriği bir işlemde "cout" a atmayı düşünün. 'cout' genellikle iş parçacığı güvenli olacak, sadece kilitleme her çağrı için açıktır, ve her bir '<<' işlemi ayrı bir çağrıdır .... Bu şekilde, uygulama kodunuzda ekstra bir kilitleme yoktur - bu sadece azalabilir paralellik. –
İlgili: [Cout synchronized/thread-safe?] (Http://stackoverflow.com/questions/6374264/is-cout-synchronized-thread-safe/6374525#6374525) – legends2k