C API

2016-04-04 19 views
3

için bir iş parçacığı güvenli C++ sarmalayıcısı yazmak için çaba harcamamıştım. API, kendiliğinden iş parçacığı için güvenli DEĞİL ise, C API 'thread-safe' C++ sarmalayıcı yazıyorum. RAII'yi kullanmaya çalıştım.C API

Bilmek istiyorum, uygulamam doğru mu? ve iş parçacığı güvenli olsun. Kodumdaki tüm yorumları takdir ediyorum. Şimdiden teşekkürler! aşağıdaki gibi

C API'sıdır sarılacak olan aşağıdaki şekilde sargının

/* an data structure which represents a connection proxy to the logger: */ 
struct cLog_Logger; 

/* connect the logger, and returns a handle to it: */ 
cLog_Logger* cLog_connect(); 

/* appends a zero terminated string to the log: */ 
void cLog_write(cLog_Logger* logger, const char* message); 

/* closes the connection with the logger: */ 
void cLog_close(cLog_Logger* logger); 

Benim uygulamasıdır:

class LoggerWrapper{ 

    public: 
     LoggerWrapper(){    //constructor 
      cLog= cLog_connect(); 
     } 

     void log(const std::string &message){ //entry point 
      cLog_write(cLog, message); 
      cLog_close(cLog); 
      } 

     ~LoggerWrapper(){  //destructor 
      delete cLog; 
     } 
    protected: 
     cLog_Logger *cLog; 
} 

Teşekkür! Bu veriyor

class LoggerWrapper{ 

public: 
    LoggerWrapper(){    //constructor 
     cLog= cLog_connect(); 
    } 

    void log(const std::string &message){ //entry point 
     cLog_write(cLog, message); 
     } 

    ~LoggerWrapper(){  //destructor 
     cLog_close(cLog); 
     delete cLog; 
    } 
protected: 
    cLog_Logger *cLog; 
} ; 

böyle kod yazmak:

+0

Konular nerededir? – Ajay

+0

@Ajay, Threads'ın dışındaki her yer sarıcı :) – user2807083

cevap

3

Ben böyle uygulamasını değiştirmeye gerek

LoggerWrapper logger ; 
logger.log("Something") ; 
logger.log("Something else) ; 

nedenle aynı nesne ile birden fazla günlüğü yapmak; aksi halde ilk çağrı kaydediciyi kapatır ve nesne işe yaramaz. İstediğin bu mu? O halde ikinci soru var: İplik güvenliği ile ne demek istiyorsun? Farklı nesnelerden aynı nesnede günlükler yapmak ister misiniz?

Sonra böyle bir mutex ve günlük işlevi içinde bir kilit bekçi ekleyebilirsiniz:

class LoggerWrapper{ 

public: 
    LoggerWrapper(){    //constructor 
     cLog= cLog_connect(); 
    } 

    void log(const std::string &message){ //entry point 
     std::lock_guard<std::mutex> guard(mutex); 
     cLog_write(cLog, message); 
     } 

    ~LoggerWrapper(){  //destructor 
     cLog_close(cLog); 
     delete cLog; 
    } 
protected: 
    cLog_Logger *cLog; 
    std::mutex mutex ; 
} ; 
+0

Muteks'in statik olmayan sınıf üyesi olarak problemi çözeceğini sanmıyorum. Düşünün, op 2 farklı iş parçacığında 2 LoggerWrapper örneği oluşturun. Boom! – user2807083

+0

@marom, 'cLog_close (cLog)' nesnesini yok ediciye taşımak için iyi bir nokta, mantığın mantıklı olup olmadığından emin olmamakla birlikte, günlük yazımı yapılır yapılmaz bağlantıyı kapatmaktı. – ulyssis2

+0

@marom, "thread safety" hakkındaki spekülasyonunuz doğru, API senkronizasyon sorununu önlemek için bir mekanizmaya sahip değil. Çözümünüz doğru görünüyor, çok teşekkürler! – ulyssis2

2

Kısa cevap: hayır değil. Öncelikle, delete yerine free() olmalıdır, çünkü c api. Yaptığınız şey, kaynak sızıntısız programınızı verebilir, ancak iş parçacığı güvenli değildir. RAII, kaynak sızıntısından kaçınmak içindir. RAII sınıfınıza statik muteks eklemek için API'nizi iş parçacığı için güvenli bir şekilde sarma etmenin basit ama etkili bir yolu yoktur.

#include <mutex> 

class LoggerWrapper{ 

public: 
    LoggerWrapper() : l(globalLock); 
    {    //constructor 
     cLog= cLog_connect(); 
    } 

    void log(const std::string &message){ //entry point 
     cLog_write(cLog, message); 
     cLog_close(cLog); 
     } 

    ~LoggerWrapper(){  //destructor 
     free(cLog); // I think here must be free(), but not sure 
    } 
protected: 
    cLog_Logger *cLog; 
    static std::mutex globalLock; 
    std::lock_guard<std::mutex> l; 
} 

std::mutex LoggerWrapper::globalLock; 
+0

teşekkürler! C++ sarmalayıcı sınıfını tartışırken, bence ree() ve silme önemli farklılıklar yaratmıyor. – ulyssis2

+0

Lock_guard üyesinin kullanımını açıklar mısınız? 'l' üyesi başlatma sırasında atanır, ancak daha sonra hiçbir şey yapmaz. – ulyssis2

+0

@ ulyssis2, lock_guard, kurucuda muteks kilidini alan ve yıkıcıda muteks kilidini bırakan RAII şablonudır. Lock_guard mevcutken, mutex'i kilitli durumda tutar. – user2807083