[英]Effort to write a thread-safe C++ wrapper of C API
I am writing a 'thread-safe' C++ wrapper of C API, while the API itself is NOT internally thread safe. 我正在编写一个C ++的“线程安全”C ++包装器,而API本身并不是内部线程安全的。 I have tried to use RAII.
我曾尝试使用RAII。
I would like to know, is my implementation correct? 我想知道,我的实施是否正确? and whether it is thread safe.
以及它是否是线程安全的。 I appreciate any comments on my code.
我感谢对我的代码的任何评论。 Thanks in advance!
提前致谢!
The C API to be wrapped is as follows, 要包装的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);
My implementation of the wrapper is as follows: 我的包装器实现如下:
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;
}
Thanks! 谢谢!
I think you need to change the implementation like this: 我认为你需要改变这样的实现:
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;
} ;
This allows you to write code like this: 这允许您编写如下代码:
LoggerWrapper logger ;
logger.log("Something") ;
logger.log("Something else) ;
so make more than one log with the same object; 所以用同一个对象制作多个日志; otherwise the first call closes the logger and the object is useless.
否则第一个调用关闭记录器,对象无用。 Is this what you want?
这是你想要的吗?
Then there is the second question: what do you mean by thread safety? 然后还有第二个问题:线程安全是什么意思? Do you want to make logs on the same object from different threads?
您是否希望从不同的线程生成相同的对象?
Then you can add a mutex and a lock guard inside log function like this: 然后你可以在日志函数中添加一个互斥锁和一个锁定保护,如下所示:
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 ;
} ;
Short answer: no it's not. 简短的回答:不,不是。 At first, I think there must be
free()
instead of delete
, because it's c
api. 起初,我认为必须有
free()
而不是delete
,因为它是c
api。 What you doing can give your resource-leak-free program, but not thread-safe. 你在做什么可以给你的资源泄漏程序,但不是线程安全的。 RAII is for avoiding leak of resources.
RAII用于避免资源泄漏。 There is straightforward but inefficient way to wrap your API for thread safe to add static mutex in your RAII class.
有一种简单但低效的方法来包装您的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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.