u1s1,其实这段代码中的task()是有一点小问题的。
#include <thread>
#include <atomic>
#include <bits/stdc++.h>
using namespace std;
template<typename Iter>
void task(Iter start,Iter end,int goal,atomic<bool>& f) {
for(;start!=end&&!f;start+=1) {
if(*start==goal) {
f=true;
cout<<"We got "<<goal<<"!"<<endl;
}
}
}
template<typename Iter>
void p_find(Iter start,Iter end,int goal) {
int num=distance(start,end);
int num_t=5;
int task_size=num/num_t;
vector<thread> bag(num_t-1);
atomic<bool> flag(false);
Iter cur_start=start;
for(int i=0;i<num_t-1;i+=1) {
Iter cur_end=cur_start;
advance(cur_end,task_size);
bag[i]=thread(task<Iter>,cur_start,cur_end,goal,ref(flag));
cur_start=cur_end;
}
task(cur_start,end,goal,ref(flag));
for(int i=0;i<num_t-1;i+=1) {
bag[i].join();
}
if(flag==false) {
cout<<"It does not exist!"<<endl;
}
}
int main() {
vector<int> v(10000,0);
v[2000]=1;
p_find(v.begin(),v.end(),1);
return 0;
}
下面这个版本应该就没问题了。加了个atomic_flag。
#include <thread>
#include <atomic>
#include <bits/stdc++.h>
using namespace std;
template<typename Iter>
void task(Iter start,Iter end,int goal,atomic<bool>& f,atomic_flag& p) {
for(;start!=end&&!f;start+=1) {
if(*start==goal&&!p.test_and_set()) {
f=true;
cout<<"We got "<<goal<<"!"<<endl;
}
}
}
template<typename Iter>
void p_find(Iter start,Iter end,int goal) {
int num=distance(start,end);
int num_t=5;
int task_size=num/num_t;
vector<thread> bag(num_t-1);
atomic<bool> flag(false);
atomic_flag print_or_not=ATOMIC_FLAG_INIT;
Iter cur_start=start;
for(int i=0;i<num_t-1;i+=1) {
Iter cur_end=cur_start;
advance(cur_end,task_size);
bag[i]=thread(task<Iter>,cur_start,cur_end,goal,ref(flag),ref(print_or_not));
cur_start=cur_end;
}
task(cur_start,end,goal,ref(flag),ref(print_or_not));
for(int i=0;i<num_t-1;i+=1) {
bag[i].join();
}
if(flag==false) {
cout<<"It does not exist!"<<endl;
}
}
int main() {
vector<int> v(10000,0);
v[2000]=1;
p_find(v.begin(),v.end(),1);
return 0;
}