C ++中的多线程程序:在标志变量上使用互斥锁

时间:2017-04-17 19:13:34

标签: c++ multithreading mutex

我目前正在研究c ++中的多线程代码,其中每个线程都设置为执行一段代码,除非全局标志变为 TRUE 。线程不会共享任何数据,但全局标志除外。我想知道最佳做法是为标志添加互斥锁。

为了简化这个问题,我将采用以下简单示例:假设您正在尝试查找大型向量是否包含给定的整数,并且您希望在多个线程之间拆分搜索。有一个全局变量,其初始值为 FALSE 。如果其中一个线程找到整数,它应该将标志设置为 TRUE ,然后所有线程都应该停止(如果某些线程执行了一些额外的操作,直到它们意识到标志已经改变,那就没关系) 。

以下代码执行此操作(我为cout上的竞争条件道歉,但我想保持代码简短)。它创建一个填充500的大向量,用500替换500中的一个,并实现搜索过程。

代码编译并且似乎有效,但我想知道在某些时候标记的读/写是否会出错。我想知道是否应该为flag变量添加互斥锁。我犹豫不决,因为(1)大多数情况下线程只会读取标志的值,(2)标志只会改变一次(它永远不会改变为假),(3)标志的值确实如此不改变线程执行中的数据(除了停止它们之外什么都不做)(4)如果线程继续几次迭代就没问题。

我是否应该只为functor中的写入部分添加互斥锁(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;

}

1 个答案:

答案 0 :(得分:0)

将标志设置为原子进行作业