I am trying to put the condition inside a function but it is throwing confusing compile time error . While if I write it in lambda function like this []{ retur i == k;} it is showing k is unidentified . Can anybody tell How to solve this problem .
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
#include <chrono>
#include <condition_variable>
using namespace std;
condition_variable cv;
mutex m;
int i;
bool check_func(int i,int k)
{
return i == k;
}
void print(int k)
{
unique_lock<mutex> lk(m);
cv.wait(lk,check_func(i,k)); // Line 33
cout<<"Thread no. "<<this_thread::get_id()<<" parameter "<<k<<"\n";
i++;
return;
}
int main()
{
thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = thread(print,i);
for(auto &t : threads)
t.join();
return 0;
}
Compiler Error:
In file included from 6:0:
/usr/include/c++/4.9/condition_variable: In instantiation of 'void std::condition_variable::wait(std::unique_lock<std::mutex>&, _Predicate) [with _Predicate = bool]':
33:30: required from here
/usr/include/c++/4.9/condition_variable:97:14: error: '__p' cannot be used as a function
while (!__p())
^
wait() takes a predicate, which is a callable unary function returning bool. wait() uses that predicate like so:
while (!pred()) {
wait(lock);
}
check_func(i,k) is a bool. It's not callable and it's a constant - which defeats the purpose. You're waiting on something that can change. You need to wrap it in something that can be repeatedly callable - like a lambda:
cv.wait(lk, [&]{ return check_func(i,k); });
Related
Consider a container of type T elements, e.g. std::vector<T> input, and an excessively time-consuming function T f(const T&, const T&). I wish to apply f on input until one single element remains - in parallel.
I am new to C++ so I adapted an existing implementation for a Thread pool pattern in C++11 to my needs, in particular this example.
Code for discussion:
#include <thread>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <memory>
#include <future>
#include <functional>
#include <stdexcept>
#include "ThreadPool.h"
template<class T>
T ParallelReduction(ThreadPool& pool, const std::vector<T>& input, const std::function<T(T,T)>& func)
{
std::queue<std::future<T>> futureResults;
std::for_each(input.begin(), input.end(), [&futureResults](T e)
{
// T -> future<T>
futureResults.push(std::async([e]{return e;}));
});
for (;;)
{
if (futureResults.size() > 1)
{
// Get two "old" partial results, forward them to func(T,T)
T a = futureResults.front().get();
futureResults.pop();
T b = futureResults.front().get();
futureResults.pop();
futureResults.push(pool.enqueue([a, b, func]{return func(a,b);}));
}
else
{
// all input and partial result elements have been processed once, return the final result
return futureResults.front().get();
}
}
}
int main(int argc, char *argv[])
{
ThreadPool pool(4);
std::vector<int> input(12);
int n = 0;
std::generate(input.begin(), input.end(), [&n]{ return ++n; });
auto sum = ParallelReduction<int>(pool, input, [](int a, int b){return a + b;});
std::cout << sum << "\n";
auto fibonacci = ParallelReduction<int>(pool, input, [](int a, int b){return a * b;});
std::cout << fibonacci << "\n";
return 0;
}
My questions:
Is it possible to implement this without introducing futureResults, i.e. a solution that works "inline" on std::vector<T>& input?
If not, can we optimize the way we assign values T to std::future<T> in the first part?
Is it more efficient to forward std::future<T> to our function func instead of T, i.e. let the child thread wait and access the value of a and b and not the main thread?
The parts inside the loop look awful - any ideas?
Where can I optimize the code?
findsmallest common multiple of 10-million numbers in the queue does not exceed 10,000
I killed 2 days to sort out but I just do not understand! please help me
#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();
}
This program does not work! how come? what's wrong? it just starts and hangs, but if you do not delete is code
if (oche.size()>9999){
std::this_thread::sleep_for(std::chrono::milliseconds(3));
std::unique_lock<std::mutex> lock(m);
} else {
and
while (!done) {
while (!notified) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}
everything works help plz
From what I understand of your problem, you have 3 problems
Conpute the least common multiple for a list of 1M elements
You want to have one thread that produces the elements and one that consumes it. They transfer it through a buffer (a queue in your case)
Your queue cannot exceed 10K elements
In my implementation I m generating the numbers randomly and using condition variables to coordinate between the threads.
Note that the LCM is associative so you can compute it recursively, not matter what the order is.
Here is the code but please DO NOT POST DIRTY CODE LIKE YOU DID NEXT TIME OR EVERYONE will kick you out.
Here is the code
#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;
}
Hope that helps,
I know that it might be a stupid question but can you tell me why the following patch of code fails? I see nothing wrong. I am trying to read integers using scanf. I have included the necessary library, but when I run the program it crashes after I read the first s. Thank you.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
int main()
{
int n, x;
scanf("%d", &n); scanf("%d", &x);
vector< pair<int, int> > moments;
for(int i = 0; i < n; ++i)
{
int f, s;
scanf("%d", &f);
scanf("%d", &s );
moments[i].first = f;
moments[i].second = s;
}
return 0;
}
That is not the way to assign values to moments since moments[i] does not yet exist. Try:
pair<int, int> thing;
thing = make_pair(f,s);
moments.push_back(thing);
instead of your assignements to moments elements.
So I am trying to use pthread libraries for Visual C++(2012) and I get this error error C4716: 'print_message' : must return a value
Here's the code
#include "stdafx.h"
#include <iostream>
#include "pthread.h"
using namespace std;
void* print_message(void *)
{
cout << "Threading\n";
}
int main()
{
pthread_t t1;
pthread_create(&t1, NULL, print_message, NULL);
cout << "Hello";
void* result;
pthread_join(t1,&result);
return 0;
}
Add return NULL; to print_message. I'll bet you need to name the argument too.
I'm creating c++ game server. The server creates many objects monster, and every monster should have its thread with specific function.
I get error :
error C2064: term does not evaluate to a function taking 0 arguments
thread.hpp(60) : while compiling class template member function 'void
boost::detail::thread_data<F>::run(void)'
monster.cpp:
#include "monster.h"
monster::monster(string temp_mob_name)
{
//New login monster
mob_name = temp_mob_name;
x=rand() % 1000;
y=rand() % 1000;
boost::thread make_thread(&monster::mob_engine);
}
monster::~monster()
{
//Destructor
}
void monster::mob_engine()
{
while(true)
{
Sleep(100);
cout<< "Monster name"<<mob_name<<endl;
}
}
monster.h:
#ifndef _H_MONSTER_
#define _H_MONSTER_
//Additional include dependancies
#include <iostream>
#include <string>
#include "boost/thread.hpp"
using namespace std;
class monster
{
public:
//Functions
monster(string temp_mob_name);
~monster();
//Custom defined functions
void mob_engine();
int x;
int y;
};
//Include protection
#endif
mob_engine is a non-static member function, so it has an implicit this argument.
Try this:
boost::thread make_thread(boost::bind(&monster::mob_engine, this));
According to this similar question boost:thread - compiler error you can even avoid using bind by simply writing:
boost::thread make_thread(&monster::mob_engine, this);
Also, you will probably want to declare a boost::thread member variable to keep a reference to the thread.