我将 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/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是: