C ++线程和互斥和条件变量

时间:2014-12-30 12:54:05

标签: multithreading c++11 mutex condition-variable

队列中最常见的1000万个数字的公倍数不超过10,000 我杀了2天整理,但我只是不明白!请帮帮我

     #include <condition_variable>
    #include <mutex>
    #include <thread>
    #include <iostream>
    #include <queue>
    #include <chrono>
    #include <cmath>
    #include <map>
    #include <cstdlib>
    #include <fstream>
    #include <ctime>
    using namespace std;

    int main()
    {
    std::map <int, int> NOK;
    map<int, int> snok;
    std::queue<int> oche;
    std::mutex m;
    std::condition_variable cond_var;
    bool done = false;
    bool notified = false;


    std::thread filev([&]() {


    //std::unique_lock<std::mutex> lock(m);
    ifstream in; // Поток in будем использовать для чтения
    int ch;
    in.open("/home/akrasikov/prog/output.txt");
    while(!in.eof()){
    if (oche.size()>9999){
    std::this_thread::sleep_for(std::chrono::milliseconds(3));
    std::unique_lock<std::mutex> lock(m);

    } else {
    in>>ch;
    oche.push(ch);
    }

    }

    notified = true;
    cond_var.notify_one();


    done = true;
    cond_var.notify_one();
    });

    std::thread nok([&]() {
    std::unique_lock<std::mutex> lock(m);
    while (!done) {
     while (!notified) { // loop to avoid spurious wakeups
    cond_var.wait(lock);
    }
    while (!oche.empty()) {
    ch=oche.front();
    oche.pop();
    int j=2;
    while (j < sqrt((double)ch)+1){

    int s=0;
    while(!(ch%j)){
    s++;
    ch/=j;
    }
    if (s > 0 && NOK[j] < s){
    NOK[j] = s;

    }
    j++;

    }
    if (NOK[ch] == 0) NOK[ch]++;
    }
    long int su=1;
    int temp=-1;
    int step=0;

    int sa=1;

    std::cout << " NOK= ";
    for (std::map<int, int>::iterator it=NOK.begin(); it!=NOK.end(); it++){
    for (int i=0; i<it->second; i++){
    su*=it->first;
    sa=it->first;


    if (temp<sa && sa >1){



    temp=sa; 
    step=1;

    } else {
    if(sa>1)
    step++;
    }

    }

    cout<< temp << "^"<< step << " * " ;

    }

    std::cout << "su = " << su << '\n';


   }

notified = false;
});


    filev.join();
    nok.join();

    }

这个程序不起作用!怎么会?怎么了?它只是启动并挂起,但如果你不删除是代码

if (oche.size()>9999){
std::this_thread::sleep_for(std::chrono::milliseconds(3));
std::unique_lock<std::mutex> lock(m);

} else {

while (!done) {
 while (!notified) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}

一切正常有用pz

1 个答案:

答案 0 :(得分:1)

根据我对您的问题的理解,您有3个问题

  1. 最不常见的多个与1M元素列表
  2. 进行争议
  3. 您希望有一个产生元素的线程和一个消耗它的线程。它们通过缓冲区(在你的情况下是一个队列)传输它
  4. 您的队列不能超过10K元素
  5. 在我的实现中,我随机生成数字并使用条件变量来协调线程。

    请注意,LCM是关联的,因此您可以递归计算它,无论订单是什么。

    以下是代码,但请不要像下次那样发布脏代码或者每个人都会将你踢出去。

    这是代码

    #include <condition_variable>
    #include <mutex>
    #include <thread>
    #include <iostream>
    #include <queue>
    #include <chrono>
    #include <cmath>
    #include <map>
    #include <cstdlib>
    #include <fstream>
    #include <ctime>
    #include <atomic>
    #include <random>
    
    using namespace std;
    
    std::mutex mutRandom;//use for multithreading for random variables
    int getNextRandom()
    {
        std::lock_guard<std::mutex> lock(mutRandom);
        // C++11 Random number generator
        std::mt19937 eng (time(NULL));                         // Mersenne Twister generator with a different seed at each run
        std::uniform_int_distribution<int> dist (1, 1000000);
        return dist(eng);                                       
    }
    
    //thread coordination
    std::mutex mut;
    std::queue<int> data_queue;
    std::condition_variable data_cond;
    std::atomic<int> nbData=0;
    std::atomic<int> currLCM=1;//current LCM
    const unsigned int nbMaxData=100000;
    const unsigned int queueMaxSize=10000;
    
    
    //Arithmetic function, nothing to do with threads
    //greatest common divider
    int gcd(int a, int b)
    {
        for (;;)
        {
            if (a == 0) return b;
            b %= a;
            if (b == 0) return a;
            a %= b;
        }
    }
    
    //least common multiple
    int lcm(int a, int b)
    {
        int temp = gcd(a, b);
    
        return temp ? (a / temp * b) : 0;
    }
    
    /// Thread related part
    
    //for producing the data
    void produceData()
    {
        while (nbData<nbMaxData)
        {
            std::unique_lock<std::mutex> lk(mut);
            data_cond.wait(lk,[]{
                return data_queue.size()<queueMaxSize;
            });
            cout<<nbData<<endl;
            ++nbData;
            data_queue.push(getNextRandom());
            data_cond.notify_one();
            lk.unlock();
        }
    
        cout<<"Producer done \n";
    }
    
    //for consuming the data 
    void consumeData()
    {
        while (nbData<nbMaxData)
        {
            std::unique_lock<std::mutex> lk(mut);
            data_cond.wait(lk,[]{
                return !data_queue.empty();
            });
            int currData=data_queue.front();
            data_queue.pop();
            lk.unlock();
            currLCM = lcm(currLCM,currData);
        }
        cout<<"Consumer done \n";
    }
    
    
    int main()
    {
        std::thread thProduce(&produceData);
        std::thread thConsume(&consumeData);
    
        thProduce.join();//to wait for the producing thread to finish before the program closes
        thConsume.join();//same thing for the consuming one
        return 0;
    }
    

    希望有所帮助,