我正在编写一个“线程安全的”#39; C API的C ++包装器,而API本身不是内部线程安全的。我试过使用RAII。
我想知道,我的实施是否正确?以及它是否是线程安全的。我感谢对我的代码的任何评论。提前谢谢!
要包装的C API如下,
/* 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);
我的包装器实现如下:
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;
}
谢谢!
答案 0 :(得分:3)
我认为你需要改变这样的实现:
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;
} ;
这允许您编写如下代码:
LoggerWrapper logger ;
logger.log("Something") ;
logger.log("Something else) ;
所以使用同一个对象制作多个日志;否则第一个调用关闭记录器,对象无用。这是你想要的吗?
然后还有第二个问题:线程安全是什么意思?你想从不同的线程中记录同一个对象吗?
然后你可以在日志函数中添加一个互斥锁和一个锁定保护,如下所示:
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 ;
} ;
答案 1 :(得分:2)
简短的回答:不,不是。首先,我认为必须有free()
而不是delete
,因为它是c
api。
你在做什么可以给你的资源泄漏程序,但不是线程安全的。 RAII用于避免资源泄漏。
有一种简单但低效的方法来包装您的API以保证线程安全,以便在您的RAII类中添加静态互斥。
#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;