C ++使用互斥字段初始化结构

Posted

技术标签:

【中文标题】C ++使用互斥字段初始化结构【英文标题】:C++ Initialize struct with mutex field 【发布时间】:2021-01-05 18:22:39 【问题描述】:

我试图弄清楚如何使用互斥体字段初始化结构,因为互斥体类型在 C++ 中不可复制或移动。

我有结构:

typedef struct sample 
  int field1;
  std::mutex mtx;
 sample_t;

我正在尝试通过以下方式对其进行初始化,但我不断收到错误消息:使用已删除的功能。我对 C++ 不是很熟悉,希望得到一些帮助!

sample_t* new_sample;
std::mutex a_mtx;
// new_sample->mtx = std::move(a_mtx); (I tried this too)
new_sample->mtx = a_mtx;
new_sample->mtx.lock();
new_sample->field1 = 2;
new_sample->mtx.unlock();

【问题讨论】:

你到底想做什么?为什么您认为需要将一个默认创建的互斥锁的值复制到另一个默认创建的互斥锁?你认为那有什么作用?你认为mutex1=mutex2; 会以某种方式使任何持有mutex2 的线程现在持有mutex1 根本不需要初始化。您已经拥有一个完整构造的 std::mutex 实例。你可以摆脱a_mtx,直接打电话给lock() 当我摆脱a_mtx 时,我会在new_sample->mtx.lock() 行出现段错误。如果我在 gdb 中打印出 new_sample,它看起来像 $1 = (new_sample *) 0x0 所以我认为我需要初始化它? @MaryMatthews 您需要初始化sample_t 对象,而不是它的成员。你的指针没有指向任何地方。 段错误是因为new_sample 是一个未初始化的指针。您可以使用sample_t* new_sample = new sample_t; 或根本不使用指针:sample_t new_sample; 【参考方案1】:

Mutex 不可复制且不可移动。但是你不需要这两个操作,你只需要创建sample_t对象-std::mutex里面会被编译器初始化。

sample_t new_sample;

new_sample.mtx.lock();
new_sample.field1 = 2;
new_sample.mtx.unlock();

或者,如果您出于某种原因确实需要指针:

// sample_t* new_sample = new sample_t;
// you should prefer smart pointers over raw pointers
std::unique_ptr<sample_t> new_sample = std::make_unique<sample_t>();

new_sample->mtx.lock();
new_sample->field1 = 2;
new_sample->mtx.unlock();

【讨论】:

【参考方案2】:

正如@JarMan 在评论中指出的那样,在 C++ 中,结构的所有字段都在创建结构时被初始化。你得到的关于“使用已删除函数”的错误告诉你,一旦结构存在,你就不能只复制已经存在的互斥锁。

但是,您确实需要实际创建结构;您拥有的代码会创建一个指针,但不会创建结构本身。所以你可能想要:

sample_t* new_sample = new sample_t;
new_sample->mtx.lock();
// ... etc

另外,请注意,在 C++ 中,声明结构时不必使用 typedef;你可以这样做

struct sample_t 
  int field1;
  std::mutex mtx;
;

【讨论】:

以上是关于C ++使用互斥字段初始化结构的主要内容,如果未能解决你的问题,请参考以下文章

初始化复杂结构,GCC 警告:已覆盖副作用的初始化字段

C基础结构体

ABAP结构体

堆内存指针从结构内的指针字段中丢失

golang结构体组合与“多态” 2021-08-06

6.5 linux内核互斥锁