Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在多个线程之间安全地共享结构_C++_Windows_Multithreading - Fatal编程技术网

C++ 在多个线程之间安全地共享结构

C++ 在多个线程之间安全地共享结构,c++,windows,multithreading,C++,Windows,Multithreading,在Windows/C++下,如果我有一个结构: struct ListItem { ListItem* next; ListItem* prev; ... } 再加上在主进程和几个动态加载的DLL中运行的多个线程,所有这些线程都需要共享上述结构,我如何阻止它们相互践踏?比如: ListItem* list = ... A list->next = ... B 我在A和B处放置了什么,以防止一次运行的线程不超过一个?列表->下一步=…?在有多个进程可以访问一

在Windows/C++下,如果我有一个结构:

struct ListItem {
    ListItem* next;
    ListItem* prev;
    ...
}
再加上在主进程和几个动态加载的DLL中运行的多个线程,所有这些线程都需要共享上述结构,我如何阻止它们相互践踏?比如:

ListItem* list = ...

A

list->next = ...

B

我在A和B处放置了什么,以防止一次运行的线程不超过一个?列表->下一步=…?

在有多个进程可以访问一个资源的情况下使用Windows互斥对象


如果所有线程都在一个进程上,则可以使用EnterCriticalSection/LeaveCriticalSection。

如果有多个进程可以访问一个资源,请使用Windows互斥对象


如果线程都在一个进程上,则可以使用EnterCriticalSection/LeaveCriticalSection。

您正在寻找同步。看看互斥


您正在寻找同步。看看互斥


主要有两种方法。一种可能是最简单的方法,就是简单地向每个线程发送它自己的数据结构副本。这样,您就不必使用同步来保护数据,因为没有线程共享另一个线程的数据

但这在很多情况下都不起作用。有时确实需要共享一个公共数据结构。在这种情况下,您需要使用某种形式的同步对象来保护数据结构。Threads提供了一些跨平台的,我相信有人会教你如何使用它们。既然你特别问过Windows,我就给你介绍一种Windows方式

你可以用一个。首先,在启动工作线程之前,需要初始化主线程中的关键部分:

int main()
{
// ...
  CRITICAL_SECTION cs;
  InitializeCriticalSection(&cs);
// ...
}
然后将指向cs的指针传递给每个工作线程。这是留作练习的。在每个工作线程中,在处理数据之前输入cs,完成后将其保留

CRITICAL_SECTION* pcs = ...; // passed in from main thread
EnterCriticalSection(pcs); // this will block until the cs is "available"
list->next = ...
LeaveCriticalSection(pcs); // makes the cs available to other threads
以上是psudocode,有很大的改进空间。例如,关键部分应包装在RAII对象中,以便在处理完后自动销毁。类似地,锁定和解锁也应该在RAII对象中完成,这样无论您如何退出线程函数,即使遇到异常,它都始终处于解锁状态


您应该注意,一个关键的_部分只能由一个进程使用。如果您需要在多个进程中使用互斥类型的对象,而不是您在这里似乎需要的对象,那么您需要使用互斥类型的对象。

有两种主要方法。一种可能是最简单的方法,就是简单地向每个线程发送它自己的数据结构副本。这样,您就不必使用同步来保护数据,因为没有线程共享另一个线程的数据

但这在很多情况下都不起作用。有时确实需要共享一个公共数据结构。在这种情况下,您需要使用某种形式的同步对象来保护数据结构。Threads提供了一些跨平台的,我相信有人会教你如何使用它们。既然你特别问过Windows,我就给你介绍一种Windows方式

你可以用一个。首先,在启动工作线程之前,需要初始化主线程中的关键部分:

int main()
{
// ...
  CRITICAL_SECTION cs;
  InitializeCriticalSection(&cs);
// ...
}
然后将指向cs的指针传递给每个工作线程。这是留作练习的。在每个工作线程中,在处理数据之前输入cs,完成后将其保留

CRITICAL_SECTION* pcs = ...; // passed in from main thread
EnterCriticalSection(pcs); // this will block until the cs is "available"
list->next = ...
LeaveCriticalSection(pcs); // makes the cs available to other threads
以上是psudocode,有很大的改进空间。例如,关键部分应包装在RAII对象中,以便在处理完后自动销毁。类似地,锁定和解锁也应该在RAII对象中完成,这样无论您如何退出线程函数,即使遇到异常,它都始终处于解锁状态


您应该注意,一个关键的_部分只能由一个进程使用。如果您需要在多个进程中使用互斥类型的对象,而不是您在这里似乎需要的对象,那么您需要使用互斥类型的对象。

根据您需要的结构,您可以使用一些无锁数据结构,如。这样,即使多个线程正在执行操作,数据结构仍然是一致的。

根据您对结构的需求,您可以使用一些无锁数据结构,如。这样,即使多个线程执行操作,数据结构仍然是一致的。

该结构如何在进程间共享?CriticalSection是需要的,或者更好的是一个封装它的lock\u guard类。我实际上没有这样做,但在Windows中可以创建进程间共享内存。将此内存中的指针强制转换为堆栈*。使用命名互斥来保护访问。Windows共享文件和内存:如何在进程间共享此结构?CriticalSection是需要的,或者更好的是一个封装它的lock\u guard类
这样做,但在Windows中可以创建进程间共享内存。将此内存中的指针强制转换为堆栈*。使用命名互斥来保护访问。Windows共享文件和内存:要做的第一件事是封装整个列表以及在类中直接访问它的所有内容,并强制任何想要访问它的内容使用该类。这将防止重复代码,并确保使用列表的任何内容都符合您提出的任何同步方法。首先要做的是将整个列表以及直接访问列表的所有内容封装在类中,并强制任何想要访问列表的内容使用该类。这将防止重复代码,并确保使用列表的任何内容都符合您提出的任何同步方法。谢谢!很抱歉,我不知道正确的单词,但在查看了您的关键部分链接后,我发现这正是我需要的:谢谢很抱歉,我不知道正确的单词,但在查看了您的关键部分链接后,我发现这正是我需要的:@史蒂夫:我想不出任何情况下,关键部分是正确的,但互斥是技术上不正确的。你能?但是,正确与最佳也不一样。@Steve:我想不出任何情况下,临界_部分是正确的,但互斥锁在技术上是错误的。你能?但再一次,正确与最优并不相同。