命名空间std中的C++互斥锁不是一种类型。

40

我正在编写一个简单的C++程序来演示锁的使用。我正在使用codeblocksgnugcc编译器。

 #include <iostream>
 #include <thread>
 #include <mutex>
 using namespace std;
 int x = 0; // shared variable

 void synchronized_procedure()
 {
    static std::mutex m;
    m.lock();
    x = x + 1;
    if (x < 5)
    {
       cout<<"hello";
    }
    m.unlock();

 }

int main()
{

   synchronized_procedure();
   x=x+2;
   cout<<"x is"<<x;
}

我遇到了以下错误:mutex in namespace std does not name a type
为什么会出现这个错误? 难道编译器不支持锁的使用吗?

8
如果你正在使用Windows系统,MinGW尚未实现线程库。我曾经有过同样的经历并希望情况不同,但至少MSVC已经可以正常运行。 - chris
1
哇,看起来,显然其中一个(仅限4.7版本)应该现在支持它。我正在下载一个进行测试,如果它最终能够工作,我会让你知道的。 - chris
嗯,对我来说根本不起作用。我不知道你会不会更幸运些。 - chris
2
哦,嘿。这个答案 实际上起作用了!确保在链接器选项中添加-static。唯一的问题是我只能找到一个与GCC 4.7.0配套的,这意味着要放弃其他一些C++11特性,直到构建出新的版本。 - chris
可能是mingw-w64线程:posix vs win32的重复问题。 - rogerdpack
10个回答

23

我也碰巧遇到了同样的问题。在Linux下,GCC可以很好地使用std::mutex。然而,在Windows上情况似乎更糟糕。在MinGW GCC 4.7.2附带的<mutex>头文件中(我相信您也在使用MinGW GCC版本),我发现mutex类在以下#if守卫下被定义:

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)

遗憾的是,在Windows上未定义_GLIBCXX_HAS_GTHREADS,运行时支持也不存在。

您可能还想直接在MinGW邮件列表上提出问题,以便一些GCC大师可以帮助您解决问题。

编辑:MinGW-w64项目提供必要的运行时支持。请查看http://mingw-w64.sourceforge.net/https://sourceforge.net/projects/mingw-w64/files/。此外,正如0xC0000022L所指出的,您需要下载POSIX线程版本(我上次忘了提到)。


6
事实证明,即使使用MinGW64,你仍然需要使用以“-posix”为后缀的与GCC相关的工具,而不是“-win32”。这显然是指所使用的线程模型。 - 0xC0000022L

23

使用POSIX线程模型来编译MINGW:

$ sudo update-alternatives --config i686-w64-mingw32-gcc
<choose i686-w64-mingw32-gcc-posix from the list>

$ sudo update-alternatives --config i686-w64-mingw32-g++
<choose i686-w64-mingw32-g++-posix from the list>

$ sudo update-alternatives --config x86_64-w64-mingw32-gcc
<choose x86_64-w64-mingw32-gcc-posix from the list>

$ sudo update-alternatives --config x86_64-w64-mingw32-g++
<choose x86_64-w64-mingw32-g++-posix from the list>

另请参阅:mingw-w64线程:posix vs win32


2
在Debian Buster上测试通过。这正是我所需要的。-std=c++0x解决方案现在已经过时,因为它现在不再必要(至少在gcc 8.3中是如此)。 - Stewart
这似乎是正确的答案。 - vy32
这个解决方案对我有用,谢谢。我只需要最后一个命令 sudo update-alternatives --config x86_64-w64-mingw32-g++ - Zion

13

这个现在已经包含在MingW(版本2013072300)中了。要包含它,您必须在MinGW安装管理器中选择pthreads包。

从MingW安装管理器中选择Pthreads包的选项


请提供系统信息,包括您的MingW版本,以便帮助其他人。 - IsakBosman
5
抱歉:Windows下的mingw32-pthreads-w32 2.10-pre-20160821-1似乎是我们能够更新到的最新版本;但仍然显示“std::mutex不是类型名称”。 - John Perry
谢谢@JohnPerry,我会看看是否有根据那个版本更新我的答案。 - IsakBosman

7

在 Mingw-builds 工具链的 'Thread model: win32' 中,至少不支持 Mutex。您必须选择具有 'Thread model: posix' 的任何工具链。经过尝试多个版本和修订版(i686 和 x86_64 体系结构),我只发现在 x86_64-4.9.2-posix-seh-rt_v3-rev1 中支持 Mutex,这个线程模型是 IMO 的决定性因素。


4

我在使用MingW-W64 7.2.0时遇到了同样的问题。我从mingw-64下载页面测试了几个不同的Windows版本,发现MinGW-W64 GCC-8.1.0支持mutex并包含pthread库。安装时,我选择了以下选项:

  • x86_64
  • posix
  • seh

我的基于pthreads的多线程代码现在可在Windows和Linux上编译和运行,无需更改。

Windows 8.1上安装的MingW版本

这个版本比我使用的7.3.0版本更精简,因为它没有CygWin环境或包管理器。我还将mingw32-make.exe复制到make.exe,这样我的Makefile就不需要修改了。安装程序会在Windows开始菜单中创建一个“运行终端”的链接。

在Windows 8.1上使用MingW构建和运行pthread应用程序


2

我使用gcc4.7.7时遇到了同样的错误。

加上“-std=c++0x”后,问题已经解决。


1
如何添加? - gab06

1
我按照以下步骤解决了问题:
  • 项目 > 构建选项...
  • 默认选择的编译器:GNU GCC 编译器
  • 在选项卡“编译器设置 / 编译器标志”中,勾选选项“让 g++ 遵循 C++11 ISO C++ 语言标准 [-std=c++11]”

1

我的gcc版本是5.4,当我在CmakeLists.txt中添加#include和-std=c++11时,我解决了这个问题:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall  -O3 -march=native -std=c++11")

0

我不知道是否适用于所有人,但另一种方法是您只需更新ndk。我正在使用ndk-r11c,它完美地工作。


1
MinGW64与Android NDK没有任何关系。 - 0xC0000022L
你是正确的,重要的一点是“11c”,它与C版本有关。 - Bastienm
@Bastienm 在 NDK 版本中的 "11c" 与 "C" 版本无关(而且 C11 与 C++11 不同,std::mutex 是 C++ 的东西,不是 C 的)。请参阅 NDK 修订历史记录。C++11 支持(其中添加了 std::mutex 到语言中)似乎是在 Android NDK r8e(2013 年 3 月)中添加的,但这与 MinGW 无关。即使在 MinGW 中支持 C++11(和 14、17 等),由于非 POSIX 线程模型,也缺少对 std::mutex 的支持。 - Thomas Perl

-9

许多标准线程库的类可以用boost替换。一个非常简单的解决方法是用几行代码更改整个标准mutex文件。

#include <boost/thread.hpp>

namespace std
{
   using boost::mutex;
   using boost::recursive_mutex;
   using boost::lock_guard;
   using boost::condition_variable;
   using boost::unique_lock;
   using boost::thread;
}

而且不要忘记链接boost线程库。


4
或许这有点过了,特别是如果你没有使用boost。 - hithwen
3
像这样扩展 std 命名空间会产生未定义行为。http://en.cppreference.com/w/cpp/language/extending_std - Ryne Wang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接