C++ moodycamel 并发队列 - 排队指针
C++ moodycamel concurrent queue - enqueue pointers
我正在尝试使用 ConcurrentQueue 将项目记录到单独线程上的文件中:
https://github.com/KjellKod/Moody-Camel-s-concurrentqueue
这个有效:
// declared on the top of the file
moodycamel::ConcurrentQueue<MyType> q; // logger queue
. . .
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(item);
. . .
// pthread
void* Logger(void* arg) {
MyType.item;
while (true)
if (!q.try_dequeue(item))
这没有(对象在出列后似乎已损坏:
// declared on the top of the file
moodycamel::ConcurrentQueue<MyType*> q; // logger queue
. . .
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(&item);
. . .
// pthread
void* Logger(void* arg) {
MyType* item;
while (true)
if (!q.try_dequeue(item))
也在 Event
中尝试过这个 - 仍然不起作用(&newdata 总是打印相同的地址):
auto newdata = std::move(data);
printf(" - pointers - new: %p old: %p\n", &newdata, &data);
q.enqueue(&newdata);
是我做错了还是队列不支持指针?
以下代码:
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(&item);
有一个主要缺陷:您将指向 local 变量的指针放入队列 item
.
Event
函数returns一到,item
的life-time就结束了,就被析构了。您保存的指向它的指针将无效。取消引用该无效指针将导致未定义的行为。
根本不需要在此处创建本地副本,您应该可以直接使用 p
,包括将其添加到队列中:
q.enqueue(p);
话虽如此,您不需要演员表
MyType item = (MyType)*p;
*p
的类型已经是MyType
。一般而言,当您觉得有必要进行这样的 C-style 转换时,您应该将其视为您做错事的标志。
如果您需要一个副本,为什么不创建一个新对象到 copy-initialize?
喜欢:
MyItem* item = new MyItem(*p);
q.enqueue(item);
你当然要记得 delete
一旦你完成了这个对象。
比使用原始 non-owning 指针更好的解决方案是使用像 std::unique_ptr
:
这样的智能指针
moodycamel::ConcurrentQueue<std::unique_ptr<MyType>> q; // logger queue
// ...
q.enqueue(std::make_unique<MyItem>(*p));
我正在尝试使用 ConcurrentQueue 将项目记录到单独线程上的文件中:
https://github.com/KjellKod/Moody-Camel-s-concurrentqueue
这个有效:
// declared on the top of the file
moodycamel::ConcurrentQueue<MyType> q; // logger queue
. . .
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(item);
. . .
// pthread
void* Logger(void* arg) {
MyType.item;
while (true)
if (!q.try_dequeue(item))
这没有(对象在出列后似乎已损坏:
// declared on the top of the file
moodycamel::ConcurrentQueue<MyType*> q; // logger queue
. . .
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(&item);
. . .
// pthread
void* Logger(void* arg) {
MyType* item;
while (true)
if (!q.try_dequeue(item))
也在 Event
中尝试过这个 - 仍然不起作用(&newdata 总是打印相同的地址):
auto newdata = std::move(data);
printf(" - pointers - new: %p old: %p\n", &newdata, &data);
q.enqueue(&newdata);
是我做错了还是队列不支持指针?
以下代码:
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(&item);
有一个主要缺陷:您将指向 local 变量的指针放入队列 item
.
Event
函数returns一到,item
的life-time就结束了,就被析构了。您保存的指向它的指针将无效。取消引用该无效指针将导致未定义的行为。
根本不需要在此处创建本地副本,您应该可以直接使用 p
,包括将其添加到队列中:
q.enqueue(p);
话虽如此,您不需要演员表
MyType item = (MyType)*p;
*p
的类型已经是MyType
。一般而言,当您觉得有必要进行这样的 C-style 转换时,您应该将其视为您做错事的标志。
如果您需要一个副本,为什么不创建一个新对象到 copy-initialize?
喜欢:
MyItem* item = new MyItem(*p);
q.enqueue(item);
你当然要记得 delete
一旦你完成了这个对象。
比使用原始 non-owning 指针更好的解决方案是使用像 std::unique_ptr
:
moodycamel::ConcurrentQueue<std::unique_ptr<MyType>> q; // logger queue
// ...
q.enqueue(std::make_unique<MyItem>(*p));