我正在嘗試使用 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);
我做錯了還是佇列不支持指標?
uj5u.com熱心網友回復:
以下代碼:
int MyCallbacks::Event(MyType* p)
{
MyType item = (MyType)*p;
q.enqueue(&item);
有一個重大缺陷:您將指向區域變數的指標排入佇列item。
一旦Event函式回傳,它的生命周期就item結束了,它被破壞了。您保存的指向它的指標將無效。取消參考該無效指標將導致未定義的行為。
根本不需要在這里創建本地副本,您應該可以p直接使用,包括將其添加到佇列中:
q.enqueue(p);
話雖如此,你不需要演員表
MyType item = (MyType)*p;
的型別*p已經是 MyType. 一般來說,當你覺得需要做這樣的 C 風格演員表時,你應該把它當作你做錯了什么的標志。
如果你需要一個副本,為什么不創建一個新物件來復制初始化呢?
喜歡:
MyItem* item = new MyItem(*p);
q.enqueue(item);
完成后,您當然必須記住delete該物件。
比使用原始非擁有指標更好的解決方案是使用智能指標,例如std::unique_ptr:
moodycamel::ConcurrentQueue<std::unique_ptr<MyType>> q; // logger queue
// ...
q.enqueue(std::make_unique<MyItem>(*p));
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/450002.html
