我当前正在处理C 中的多线程代码,在该代码中,将每个线程设置为执行一块代码,除非全局标志变为 true 。除全局标志外,线程不会共享任何数据。我想知道最好的做法是否是为国旗添加一个哑光。
为了使这个问题保持简单,我将求助于以下琐碎的示例:假设您正在尝试查找大型向量是否包含给定的整数,并且您想在几个线程之间将搜索分开。有一个全局变量,其初始值为 false 。如果其中一个线程找到了整数,则应将标志设置为 true ,并且所有线程都应在之后停止(如果某些线程执行一些额外的操作是可以的,直到他们意识到标志已更改为止(。
以下代码执行此操作(对于COUT的比赛条件,我深表歉意,但我想简短代码(。它创建了一个填充500的大型矢量,用100替换了500个,并实现了搜索过程。
代码编译并似乎有效,但是我想知道在某个时候,标志的读/写入是否会出现问题。我想知道是否应该为标志变量添加一个哑光。我很犹豫,因为(1(在大多数情况下,线程只会读取标志的值,(2(标志只会更改一次(它永远不会更改为false(,(3(标志的值为不要更改线程执行中的数据(除了停止它们之外,除了停止它们之外别无其他操作((4(如果线程继续进行一些迭代,则可以。
我也许应该只为函子中的写作部分添加一个mutex锁(flag = true(?
vector <int> a;
bool flag = false;
int size = 100000000
class Fctor {
int s;
int t;
public:
Fctor(int s, int t) : s(s), t(t) {}
\ finds if there is a 100 in the vector between positions s and t
void operator()() {
int i = 0;
for (i = s; i < t; i++) {
if (flag == true) break;
if (a[i] == 100) {
flag = true;
break;
}
}
cout << s << " " << t << " " << flag << " " << i << "n";
}
};
int main() {
a = vector<int> (8 * size, 500); \creates a vector filled with 500
a[2*size+1] = 100; // This position will have a 100
chrono::high_resolution_clock::time_point begin_time =
chrono::high_resolution_clock::now();
int cores = 4;
vector<std::thread> threads;
int num = 8/cores;
int s = 0;
int t = num * size;
Fctor fctor(s, t);
std::thread th(fctor);
threads.push_back(std::move(th));
for (int i = 1; i < cores; i++) {
int s1 = i * num * size+1;
int t1 = (i+1) * num * size;
Fctor fctor1(s1, t1);
std::thread th1(fctor1);
threads.push_back(std::move(th1));
}
for (std::thread& th : threads) {
th.join();
}
chrono::high_resolution_clock::time_point end_time =
chrono::high_resolution_clock::now();
chrono::duration<double> time_span =
chrono::duration_cast<chrono::duration<double> >(end_time -
begin_time);
cout << "Found in: "<< time_span.count() << " seconds. n";
return 0;
}
将标志设置为原子