C++ std::condition_变量::等待不释放RaspberryPi上的锁

C++ std::condition_变量::等待不释放RaspberryPi上的锁,c++,multithreading,raspberry-pi,g++,condition-variable,C++,Multithreading,Raspberry Pi,G++,Condition Variable,我有一个在Ubuntu上为RaspberryPi(3)交叉编译的项目,使用来自git://github.com/raspberrypi/tools.git. 我想使用线程同步,但似乎没有释放提供给它的互斥锁,如文档中所述。以下是在RaspberryPi上重现问题的简化代码(为了更好地可视化问题,存在过多的日志记录): 这让我相信代码很好,RaspberryPi交叉编译或标准库存在问题。我是否遗漏了什么,这个问题是否有解决方案 编辑: 这个问题最初是在一个依赖于boost和socket.io-cl

我有一个在Ubuntu上为RaspberryPi(3)交叉编译的项目,使用来自git://github.com/raspberrypi/tools.git. 我想使用线程同步,但似乎没有释放提供给它的
互斥锁
,如文档中所述。以下是在RaspberryPi上重现问题的简化代码(为了更好地可视化问题,存在过多的日志记录):

这让我相信代码很好,RaspberryPi交叉编译或标准库存在问题。我是否遗漏了什么,这个问题是否有解决方案

编辑: 这个问题最初是在一个依赖于boost和socket.io-client的大型项目中发现的。我将
main
简化为问题中的一个,但没有删除其余的代码。它的编译和链接方式如下:

[...]
arm-linux-gnueabihf-g++ -std=c++1y -I%SRC_DIR%/rapidjson/include -I%SRC_DIR%/boost_1_65_0/install/include -I%SRC_DIR%/socket.io-client-cpp/build/include -O3 -g -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.o" -o "main.o" "../main.cpp"
[...]
arm-linux-gnueabihf-g++ -L%SRC_DIR%/boost_1_65_0/install-arm/lib -L%SRC_DIR%/socket.io-client-cpp/build-arm/lib/Release -L%SRC_DIR%/openssl/build-arm/lib -static -pthread -o "main" [...] ./main.o [...] -lsioclient -lboost_system -lssl -lcrypto -ldl
如果其他对象文件替换为[…],socket.io-client需要libssl。但是,如果我只使用
arm-linux-gnueabihf-g++-pthread-std=c++1y-O3-g-Wall-o main1 main1.cpp编译发布的代码段,它在RaspberryPi上也可以正常工作,因此可能不是交叉编译工具的问题。有没有可能是某个依赖项导致了发生的事情?

试试这个

std::cout << "locking in main" << std::endl;
std::unique_lock<std::mutex> lock(m);
std::cout << "locked in main" << std::endl;

std::cout << "starting thread" << std::endl;
std::thread t([&cv, &m, &ok]() {
    std::cout << "locking in thread" << std::endl;
    std::unique_lock<std::mutex> lock(m);
    std::cout << "locked in thread" << std::endl;
    ok = true;
    std::cout << "unlocking in thread" << std::endl;
    std::cout << "signalling cv" << std::endl;
    cv.notify_one();
});

std::cout << "starting wait" << std::endl;
while(!ok)
    cv.wait(lock);
std::cout << "finished waiting: " << ok << std::endl;

std::cout << "unlocking in main" << std::endl;
lock.unlock();
std::cout << "joining thread" << std::endl;
t.join();
std::cout << "thread joined" << std::endl;

std::cout看来我的链接器命令不正确,这(可能)导致
pthread
被静态链接,这是由于交叉编译,不是RaspberryPi上系统所需的正确版本。根据我的问题编辑,我原来的错误(简化)链接命令如下:

arm-linux-gnueabihf-g++ -Lsome_dirs -static -pthread -o "main" ./main.o ./some_object_files -lsome_libs
在单个main.cpp文件的简单情况下,此类链接选项在创建线程时报告了一个错误:
在抛出“std::system\u error”的实例后终止调用what():启用多线程以使用std::thread:不允许操作
。这一开始让我很不舒服,但实际上是一条有价值的线索

为了解决这个问题,我必须修改linker命令以静态链接库,我需要静态链接,同时动态链接pthread,如下所示:

arm-linux-gnueabihf-g++ -o "main" ./main.o ./some_object_fiels -Lsome_dirs -Wl,-Bstatic -lsome_libs -Wl,-Bdynamic -ldl -pthread

如何编译它?日志只显示在主线程超时之前没有在线程中执行获取锁的操作。您是否尝试过将
等待
替换为简单的
等待
?超时前不获取锁和根本不获取锁是两码事。
arm-linux-gnueabihf-g++ -Lsome_dirs -static -pthread -o "main" ./main.o ./some_object_files -lsome_libs
arm-linux-gnueabihf-g++ -o "main" ./main.o ./some_object_fiels -Lsome_dirs -Wl,-Bstatic -lsome_libs -Wl,-Bdynamic -ldl -pthread