我需要对以下代码块进行一些澄清。我正在研究类似编码的东西,我想了解它是如何工作的。 Google上没有很多提及,我找到的唯一一个技术太难以理解了。
在以下代码中,线程和非线程函数具有不同的输出。那是为什么?
#include <boost/thread.hpp>
#include <iostream>
#include <stdio.h>
using namespace std;
void fTry1(const char&);
void fTry2(const char&);
int main()
{
boost::thread tTry1, tTry2;
const char *a = "efgh";
tTry1 = boost::thread(fTry1, *a);
fTry2(*a);
tTry1.join();
return 0;
}
void fTry1(const char& a)
{
cout << "Thread" << endl;
cout << &a << endl;
}
void fTry2(const char& a)
{
cout << "Non-thread" << endl;
cout << &a << endl;
}
示例输出:
Non-thread
efgh
Thread
e<garbage data>
如果我更改以下行
cout << &a << endl;
到
cout << a << endl;
输出变为类似
Non-thread
e
Thread
e
再次,为什么?
-
我正在处理的代码使用数字2,但传递的字符串是文件夹的路径,所以我想要整个字符串,而不仅仅是第一个字符。但由于我不了解它是如何工作的,因此我无法轻易地对其进行更改。
答案 0 :(得分:6)
默认情况下,传递给if(open(my $jobprofile, "./profiles/$vitem[0].profile")) {
my @jobprofiletemp = <$jobprofile>;
close($jobprofile);
@proftemplates = grep /.dat/,@jobprofiletemp;
my $strproftemp = $proftemplates[0];
my ($tempksh) = $strproftemp =~ / ([^_]*)./;
print "tempksh: $tempksh","\n";
} else { warn "problem opening ./$_\n\n"; }
的参数将由boost::thread
“捕获”。要通过value
捕获它们,您必须使用reference
;
boost::ref
这与lambda函数非常相似,例如:
tTry1 = boost::thread(fTry1, boost::ref(*a));
注意:
小心地将const char *a = "efgh";
const char &c = *a;
auto garbage = [c]() { // c captured by value
cout << &c << endl;
};
auto works = [&c]() { // c captured by ref
cout << &c;
};
garbage();
works();
或references
传递给新线程,因为在新线程使用它时需要确保它们保持有效。但是,在您的独特情况下,这不适用,因为字符串文字pointers
具有efgh
,因此您无论如何都是安全的。
答案 1 :(得分:3)
const char *a = "efgh";
中的字符串文字使用隐藏的终止符'\0'
进行编译。
当您像*a
一样传递它时,您将其取消引用它。你基本上只传递一个角色。这对于非线程函数是可行的,因为如果使用&a
获取字符a
的地址,使其成为c字符串,它仍将指向字符串文字{{1}其中包括终结符。 "efgh"
将继续打印,直到它到达终止符。
但是,我怀疑,当你将cout
传递给*a
时,它实际上会复制角色,但只复制角色,而不是整个字符串。当你稍后使用boost::thread
将其变回c风格的字符串时,没有更多的终结符字符,因此&a
将继续打印,并且你会看到垃圾。
当您将cout
更改为cout << &a << endl;
时,您告诉cout << a << endl;
您只能打印1个字符。因此它只会打印1。
您使用cout
来提问,为什么不使用c++
?