İzlenecek yol: Agent tabanlı bir uygulama oluşturma
Bu konuda temel aracı tabanlı uygulama oluşturma açıklanmaktadır. Bu izlenecek yolda, bir metin dosyasından veri okur, zaman uyumsuz bir aracısı oluşturabilirsiniz. Uygulama, dosyanın içeriğini, sağlama toplamını hesaplamak için Adler-32 sağlama algoritması kullanır.
Önkoşullar
Bu izlenecek yolu tamamlamak için aşağıdaki konuları anlamak gerekir:
Bölümler
Bu izlenecek yolda, aşağıdaki görevleri gerçekleştirmek gösterilmiştir:
Konsol uygulaması yaratmak
File_reader sınıfı oluşturma
File_reader sınıfı uygulamada kullanma
Konsol uygulaması yaratmak
Bu bölümde programın kullanacağı üstbilgi dosyalarına başvuran bir Visual c++ konsol uygulaması oluşturmak nasıl gösterir.
Visual c++ uygulama Win32 konsol uygulaması Sihirbazı'nı kullanarak oluşturmak için
Üzerinde Dosya menüsünde'ı Yeni[NULL]'ı Proje görüntülemek için Yeni bir proje iletişim kutusu.
İçinde Yeni proje Seç iletişim kutusunda Visual c++ düğümünde proje türleri bölmesi ve seçin Win32 Console Application , şablonları bölmesi. Örneğin, proje için bir ad yazın BasicAgentve i Tamam görüntülemek için Win32 konsol uygulaması Sihirbazı.
İçinde Win32 konsol uygulaması Sihirbazı iletişim kutusunu tıklatın Son.
Stdafx.h aşağıdaki kodu ekleyin.
#include <agents.h> #include <string> #include <iostream> #include <algorithm>
Üstbilgi dosyası agents.h işlevselliğini içerir concurrency::agent sınıfı.
Oluşturma ve çalışan uygulama başarıyla oluşturulduğunu doğrulayın. Uygulama üzerinde oluşturmak için Yapı menüsünde'ı Build Solution. Uygulama başarıyla oluşturur, tıklatarak uygulamayı çalıştırmak Start Debugging komutunu , Debug menü.
Top
File_reader sınıfı oluşturma
Bu bölüm nasıl oluşturulacağını gösterir file_reader sınıfı. Her Aracısı kendi güvenlik bağlamında çalışmayı gerçekleştirmek için çalışma zamanı zamanlar. Bu nedenle, iş eşzamanlı olarak gerçekleştirir, ancak zaman uyumsuz olarak diğer bileşenlerle etkileşime Aracısı oluşturabilirsiniz. file_reader Sınıf belirli bir girdi dosyasındaki verileri okur ve belirli hedef bileşeni için bu dosyadan veri gönderir.
File_reader sınıfı oluşturmak için
Yeni bir c++ üstbilgi dosyası projenize ekleyin. Bunu yapmak için sağ Üstbilgi dosyaları düğümünde Solution Explorer,'ı Ekle[NULL]'ı New Item. İçinde şablonları bölmesinde seçin Üstbilgi dosyası (.h). İçinde Add New Item iletişim kutusunda, tür file_reader.h , ad kutusunu tıklatıp ardından Ekle.
File_reader.h aşağıdaki kodu ekleyin.
#pragma once
File_reader.h adlı bir sınıf oluşturmak file_reader , türeyen agent.
class file_reader : public concurrency::agent { public: protected: private: };
Aşağıdaki veri üyeleri ekleme private sınıfının bir bölümü.
std::string _file_name; concurrency::ITarget<std::string>& _target; concurrency::overwrite_buffer<std::exception> _error;
_file_name Aracısı okur dosya adı üyesidir. _target Üye olduğu bir concurrency::ITarget nesne agent içeriğini bir dosyaya yazar. _error Üye tutan Aracısı ömrü sırasında oluşan hata.
Eklemek için aşağıdaki kodu file_reader kurucusuna public bölümünde file_reader sınıfı.
explicit file_reader(const std::string& file_name, concurrency::ITarget<std::string>& target) : _file_name(file_name) , _target(target) { } explicit file_reader(const std::string& file_name, concurrency::ITarget<std::string>& target, concurrency::Scheduler& scheduler) : agent(scheduler) , _file_name(file_name) , _target(target) { } explicit file_reader(const std::string& file_name, concurrency::ITarget<std::string>& target, concurrency::ScheduleGroup& group) : agent(group) , _file_name(file_name) , _target(target) { }
Her kurucu aşırı ayarlar file_reader veri üyeleri. İkinci ve üçüncü kurucusu aşırı aracınız ile belirli bir Zamanlayıcı kullanmak uygulamanızı sağlar. İlk aşırı varsayılan Zamanlayıcı ile aracınız kullanır.
Ekleme get_error yöntemi ortak bölümüne file_reader sınıfı.
bool get_error(std::exception& e) { return try_receive(_error, e); }
get_error Yöntemi Aracısı ömrü sırasında oluşan hata alır.
Implement concurrency::agent::run yöntemi protected sınıfının bir bölümü.
void run() { FILE* stream; try { // Open the file. if (fopen_s(&stream, _file_name.c_str(), "r") != 0) { // Throw an exception if an error occurs. throw std::exception("Failed to open input file."); } // Create a buffer to hold file data. char buf[1024]; // Set the buffer size. setvbuf(stream, buf, _IOFBF, sizeof buf); // Read the contents of the file and send the contents // to the target. while (fgets(buf, sizeof buf, stream)) { asend(_target, std::string(buf)); } // Send the empty string to the target to indicate the end of processing. asend(_target, std::string("")); // Close the file. fclose(stream); } catch (const std::exception& e) { // Send the empty string to the target to indicate the end of processing. asend(_target, std::string("")); // Write the exception to the error buffer. send(_error, e); } // Set the status of the agent to agent_done. done(); }
run Yöntemi dosya açılır ve buradan verileri okur. run Yöntemi, dosya işleme sırasında oluşan hataları yakalamak için özel durum işleme kullanır.
Bu yöntem veri dosyasından okur her zaman onu çağıran concurrency::asend hedef arabellek veri göndermek için işlevi. İşleme sonunu belirtmek için hedef arabellek boş bir dize gönderir.
Aşağıdaki örnek file_reader.h tam içeriğini gösterir.
#pragma once
class file_reader : public concurrency::agent
{
public:
explicit file_reader(const std::string& file_name,
concurrency::ITarget<std::string>& target)
: _file_name(file_name)
, _target(target)
{
}
explicit file_reader(const std::string& file_name,
concurrency::ITarget<std::string>& target,
concurrency::Scheduler& scheduler)
: agent(scheduler)
, _file_name(file_name)
, _target(target)
{
}
explicit file_reader(const std::string& file_name,
concurrency::ITarget<std::string>& target,
concurrency::ScheduleGroup& group)
: agent(group)
, _file_name(file_name)
, _target(target)
{
}
// Retrieves any error that occurs during the life of the agent.
bool get_error(std::exception& e)
{
return try_receive(_error, e);
}
protected:
void run()
{
FILE* stream;
try
{
// Open the file.
if (fopen_s(&stream, _file_name.c_str(), "r") != 0)
{
// Throw an exception if an error occurs.
throw std::exception("Failed to open input file.");
}
// Create a buffer to hold file data.
char buf[1024];
// Set the buffer size.
setvbuf(stream, buf, _IOFBF, sizeof buf);
// Read the contents of the file and send the contents
// to the target.
while (fgets(buf, sizeof buf, stream))
{
asend(_target, std::string(buf));
}
// Send the empty string to the target to indicate the end of processing.
asend(_target, std::string(""));
// Close the file.
fclose(stream);
}
catch (const std::exception& e)
{
// Send the empty string to the target to indicate the end of processing.
asend(_target, std::string(""));
// Write the exception to the error buffer.
send(_error, e);
}
// Set the status of the agent to agent_done.
done();
}
private:
std::string _file_name;
concurrency::ITarget<std::string>& _target;
concurrency::overwrite_buffer<std::exception> _error;
};
Top
File_reader sınıfı uygulamada kullanma
Bu bölümde nasıl kullanılacağını gösteren file_reader sınıfı, bir metin dosyasının içeriğini okumak için. Ayrıca nasıl oluşturulacağını gösteren bir concurrency::call bu dosya veri alır ve kendi Adler-32 sağlama toplamı hesaplar nesne.
File_reader sınıfı, uygulamanızda kullanmak için
BasicAgent.cpp aşağıdakileri ekleyin #include ifadesi.
#include "file_reader.h"
BasicAgent.cpp aşağıdakileri ekleyin using yönergeleri.
using namespace concurrency; using namespace std;
De _tmain işlev, oluşturma bir concurrency::event son işlem sinyalleri nesnesi.
event e;
Oluşturma bir call nesne verileri aldığında, sağlama toplamı güncelleştirir.
// The components of the Adler-32 sum. unsigned int a = 1; unsigned int b = 0; // A call object that updates the checksum when it receives data. call<string> calculate_checksum([&] (string s) { // If the input string is empty, set the event to signal // the end of processing. if (s.size() == 0) e.set(); // Perform the Adler-32 checksum algorithm. for_each(begin(s), end(s), [&] (char c) { a = (a + c) % 65521; b = (b + a) % 65521; }); });
Bu call de nesne ayarlar event nesne boş dize sonu işleme sinyal aldığında.
Oluşturma bir file_reader , bu dosyanın içeriğini okuyabileceğini dosya sınama.txt ve nesne call nesnesi.
file_reader reader("test.txt", calculate_checksum);
Aracısı başlatmak ve bitirmek bekleyin.
reader.start(); agent::wait(&reader);
Bekle call tüm verileri almak ve bitirmek için nesne.
e.wait();
Dosya okuyucu hataları için denetleyin. Hiçbir hata oluştu, son Adler-32 toplamını hesaplamak ve konsola yazdıracak.
std::exception error; if (reader.get_error(error)) { wcout << error.what() << endl; } else { unsigned int adler32_sum = (b << 16) | a; wcout << L"Adler-32 sum is " << hex << adler32_sum << endl; }
Aşağıdaki örnek, BasicAgent.cpp dosyanın tamamını gösterir.
// BasicAgent.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "file_reader.h"
using namespace concurrency;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
// An event object that signals the end of processing.
event e;
// The components of the Adler-32 sum.
unsigned int a = 1;
unsigned int b = 0;
// A call object that updates the checksum when it receives data.
call<string> calculate_checksum([&] (string s) {
// If the input string is empty, set the event to signal
// the end of processing.
if (s.size() == 0)
e.set();
// Perform the Adler-32 checksum algorithm.
for_each(begin(s), end(s), [&] (char c) {
a = (a + c) % 65521;
b = (b + a) % 65521;
});
});
// Create the agent.
file_reader reader("test.txt", calculate_checksum);
// Start the agent and wait for it to complete.
reader.start();
agent::wait(&reader);
// Wait for the call object to receive all data and complete.
e.wait();
// Check the file reader for errors.
// If no error occurred, calculate the final Adler-32 sum and print it
// to the console.
std::exception error;
if (reader.get_error(error))
{
wcout << error.what() << endl;
}
else
{
unsigned int adler32_sum = (b << 16) | a;
wcout << L"Adler-32 sum is " << hex << adler32_sum << endl;
}
}
Top
Örnek giriş
Bu girdi dosyası text.txt örnek içeriği şöyledir:
The quick brown fox
jumps
over the lazy dog
Örnek Çıktı
Örnek giriş ile kullanıldığında, bu programı aşağıdaki çıktıyı üretir:
Adler-32 sum is fefb0d75
Güçlü programlama
Veri üyeleri eşzamanlı erişimi engellemek için çalışmayı gerçekleştiren yöntemleri ekleme önerilir protected veya private sınıfının bir bölümü. Yalnızca bilgisayardan Aracısı veya ileti gönderip yöntemleri ekleme public sınıfının bir bölümü.
Her zaman concurrency::agent:: Bitti aracınız Tamamlandı durumuna geçmek için yöntem. Gelen döndürmeden önce genelde bu yöntemi çağırın run yöntemi.
Sonraki Adımlar
Aracı tabanlı bir uygulama başka bir örnek için bkz: İzlenecek yol: kilitlenme önlemek için JOIN kullanmak.
Ayrıca bkz.
Görevler
İzlenecek yol: kilitlenme önlemek için JOIN kullanmak