gpt4 book ai didi

c++ - 将 std::sub_match 作为参数传递给 std::thread 时出了什么问题?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:25 25 4
gpt4 key购买 nike

我将 std::sub_match 作为参数传递给 std::thread(请参阅下面的示例代码)。线程函数需要一个 const 字符串引用。 sub_match 可以转换为字符串。所以一切都可以正常编译。

但有时函数会收到错误的字符串。当我在将 sub_match 传递给线程之前将其转换为字符串时,它会按预期工作。有什么区别?

我认为这是一个竞争条件,因为当线程执行时,原始的 sub_match 可能不再存在。但我认为线程的参数无论如何都会被复制。我如何找出哪些参数可以安全传递给线程,哪些不安全?

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <regex>
#include <unistd.h>

class test_t {
public:
test_t(void) {}
~test_t(void) {}

void start(void){
//-------------------------------------------------
// Do some memory allocation.
// The error seems to appear faster with that.
std::vector<std::string> vec;
for(unsigned int i = 0; i < 1000; ++i) {
vec.push_back("test_test_test");
}
//-------------------------------------------------

std::string event = "operating";
std::smatch match;
std::regex expr("\\(operating\\)",
std::regex_constants::icase |
std::regex_constants::basic);

if(std::regex_match(event, match, expr)) {
std::cout << "start thread" << std::endl;
m_thread = std::thread(&test_t::thread_func, this, match[1]); //NOK
// m_thread = std::thread(&test_t::thread_func, this, match[1].str()); // OK
// m_thread = std::thread(&test_t::thread_func, this, (std::string)match[1]); // OK
m_thread.detach();
std::cout << "thread started" << std::endl;
}
}

private:
std::thread m_thread;

void thread_func(const std::string& string) {
if(string != "operating") {
std::cout << "ERROR: string: \"" << string << "\"" << std::endl;
exit(EXIT_FAILURE);
} else {
std::cout << "string: \"" << string << "\"" << std::endl;
}
}
};

int main(int argc, char** argv) {
test_t test;
while(1) {
test.start();
usleep(100);
}
return 0;
}

编译信息:

Compiled with: g++ --std=c++11 -pthread -o test main.cpp
g++ --version: g++ (SUSE Linux) 4.8.5

预期输出:

start thread
thread started
string: "operating"
(repeat)

实际输出:

start thread
thread started
string: "operating"
ERROR: string: "test_test"

最佳答案

std::smatch

operator[] 返回 sub_match,它可以被视为匹配字符的迭代器对。

调用regex_match后,只要event存在,就可以使用operator[]访问子匹配。当 event 被删除时(你没有加入你的线程,所以 start 立即返回并且 event 被销毁),子匹配有悬空指针和不应访问。


m_thread = std::thread(&test_t::thread_func, this, match[1]);

这是行不通的,因为当函数超出范围时,事件将被删除并且子匹配具有悬空指针。


m_thread = std::thread(&test_t::thread_func, this, match[1].str());

这是有效的,因为 str() 返回匹配字符串的拷贝。


m_thread = std::thread(&test_t::thread_func, this, (std::string)match[1]);

这也有效,因为临时字符串是基于子匹配 match[1] 创建的,并且临时字符串被传递到线程中。

关于c++ - 将 std::sub_match 作为参数传递给 std::thread 时出了什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56970215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com