I am trying to wrap my head around std::async and std::futures introduced in C++11.
#include <iostream>
#include <list>
#include <functional>
#include <vector>
#include <algorithm>
#include <thread>
#include <unistd.h>
#include <string>
#include <future>
using namespace std;
int hog_cpu()
{
cout << "hog_cpu" << endl;
volatile unsigned long long i = 0;
for(i = 0; i < 1000000000ULL ; i++);
return 50;
}
int hog_cpu_ex()
{
cout << "hog_cpu_ex" << endl;
volatile unsigned long long i = 0;
for(i = 0; i < 1000000000ULL ; i++);
return 500;
}
int main()
{
cout << "start threads asynchronously" << endl;
std::future<int> f1 = std::async(std::launch::async, hog_cpu);
std::future<int> f2 = std::async(std::launch::async, hog_cpu_ex);
cout << "Get the Results" << endl;
int r1 = f1.get();
int r2 = f2.get();
cout << "result 1: " << r1 << endl;
cout << "result 2: " << r2 << endl;
return 0;
}
The output of the above program that I get is shown below.
start threads asynchronously
Get the Results
hog_cpu_ex
hog_cpu
result 1: 50
result 2: 500
Process finished with exit code 0
My question is since I use std::launch::async the execution should start immideately using another thread. Where as the output tells me that it prints the line Get the results and then only the execution starts. (As evident from the logs above). Also hog_cpu_ex starts before hog_cpu. Can someone explain why this might be happening.
When you do
std::future<int> f1 = std::async(std::launch::async, hog_cpu);
std::future<int> f2 = std::async(std::launch::async, hog_cpu_ex);
You spin up two more threads of execution. Then the main thread keeps going after it calls each line and won't stop until it hits
int r1 = f1.get();
if f1 hasn't finished yet. Since the main thread keeps going and spinning up a thread takes some time it is pretty reasonable to see Get the Results print before the threads even start.
As for why do you see
hog_cpu_ex
hog_cpu
instead of the opposite is due to your operating system. It has control over which threads run and when so it is quite possible that it puts f1 to sleep, has space for f2 so it starts it running, and then starts f1 sometime after that.
Related
I want to create two child processes with some iterations in them so that iteration l in process X always executes after iteration l+1 in process Y.
#include <stdio.h>
#include <unistd.h>
#include <bits/stdc++.h>
#include <sys/wait.h>
#include <semaphore.h>
using namespace std;
sem_t mut;
int x = 2;
int main()
{
int cpX = fork();
sem_init(&mut, 1, 1);
if (cpX == 0)
{
//child A code
for (int i = 0; i < 10; i++)
{
sem_wait(&mut);
cout << "Inside X:" << getpid() << ", " << i << '\n';
sleep(rand() % 5);
}
exit(0);
}
else
{
int cpY = fork();
if (cpY == 0)
{
//child B code
for (int i = 0; i < 10; i++)
{
cout << "Inside Y:" << getpid() << ", " << i << '\n';
sleep(rand() % 5);
sem_post(&mut);
}
//sem_wait(&mut);
exit(0);
}
else
{
//sleep(50);
//wait(NULL);
//wait(NULL);
exit(0);
// wait(NULL);
}
}
}
However here, X executes once, and then Y starts executing and X never executes again. Why is this happening?
The parent/child during a fork is doing a copy so they are not referring to the same semaphore object. Hence, mut is not shared as what you assumed. Your snippet is near correct you just need to do minor changes to work as you expect.
Since you are using an unnamed semaphore, you need to instantiate the semaphore object in a shared area:
#include <sys/mman.h>
sem_t *mut = (sem_t*)mmap(NULL, sizeof(*mut), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS, -1, 0);
sem_init(mut, 1, 1);
With this minor adjustments, your snippet above now works as expected as they are now referring to the same semaphore object.
Also, some tips: sem_post is an unblocking call, whereas sem_wait is a blocking call. You need to be also aware that a signal sent by sem_post could get lost when nobody is waiting on the semaphore during that moment.
The best reference of this kinds of things is Unix Network Programming: Interprocess Communication by Richard Stevens
I was experimenting with futures and promises and constructed a simple, although stupid example. In fact very stupid, but let's leave it.
I cannot understand why the following program doesn't wait for the input from user. It prints the slogan for the user to provide some number, but it doesn't wait. I know that similar problems were discussed here and on other forums and usually the answer was that the user forgot to join the thread. But I am joining the thread and even though this code doesn't work. What am I missing?
#include <iostream>
#include <chrono>
#include <future>
#include <memory>
using namespace std;
using namespace std::chrono_literals;
shared_ptr<promise<int>> prom;
auto fun()
{
prom = make_shared<promise<int>>();
auto ret = prom->get_future();
return ret;
}
int main(int argc, char* argv[])
{
thread t{ [] {
while(!prom){
cout << "Waiting for a promise" << endl;
std::this_thread::sleep_for(1s);
}
std::this_thread::sleep_for(1s);
cout << "OK, got the promise, now enter some value: " << endl;
int val;
cin >> val;
prom->set_value(val);
}};
std::this_thread::sleep_for(2s);
auto fut = fun();
t.join();
int v = fut.get();
cout << "You entered: " << v << endl;
}
Working example:
https://wandbox.org/permlink/AzTQer4rNkJcMBC7
I just get stuck in this code, I assumed that the code locks the global variable "a" for 30 seconds but the output doesn't satisfy this assumption. Could any one help me figure out why this happens and another question is that is there any function to lock required variable for a specific time, being specified by the programmer. Thank you in advanced for your consideration.
#include <iostream>
#include <ctime>
#include <pthread.h>
#include <time.h>
#include <chrono>
using namespace std;
// std::chrono::seconds interval(100);
timed_mutex test_mutex;
int a = 0;
void * write(void * args)
{
auto start=std::chrono::steady_clock::now();
test_mutex.try_lock_until(start+std::chrono::seconds(30));
a = 2;
cout << "Here is place #" << a << endl;
test_mutex.unlock();
pthread_exit(NULL);
}
int main()
{
auto start=std::chrono::steady_clock::now();
pthread_t check;
pthread_create(&check, NULL, &write, NULL);
test_mutex.try_lock_until(start+std::chrono::seconds(30));
a = 1;
cout << "Here is place #" << a << endl;
test_mutex.unlock();
pthread_join(check, NULL);
return 0;
}
std::timed_mutex::try_lock_until returns either:
true when the mutex is acquired, or
false if it timed out (waited as long as allowed) trying to lock the mutex
Note that this code is buggy anyway, because it doesn't check the return value. So, a can be written even if the mutex was not acquired.
I'm making my first multithreaded program and having some issues. I based the code on an example I found online, which worked fine until I made my changes. The main function below makes several threads which run another function. That function runs instances of another c++ program that I wrote which works fine. The issue is that after the program creates all the threads, it stops running. The other threads continue to run and work fine, but the main thread stops, not even printing out a cout statement I gave it. For example, if I run it the output is:
Enter the number of threads:
// I enter '3'
main() : creating thread, 0
this line prints every time
main() : creating thread, 1
this line prints every time
main() : creating thread, 2
this line prints every time
this is followed by all the output from my other program, which is running 3 times. But the main function never prints out "This line is never printed out". I'm sure there is some fundamental misunderstanding I have of how threads work.
#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <pthread.h>
#include <stdio.h>
#include <string>
#include <sstream>
#include <vector>
#include <fstream>
#include <unistd.h>
using namespace std;
struct thread_data{
int thread_id;
};
void *PrintHello(void *threadarg)
{
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
stringstream convert;
convert << "./a.out " << my_data->thread_id << " " << (my_data->thread_id+1) << " " << my_data->thread_id;
string sout = convert.str();
system(sout.c_str());
pthread_exit(NULL);
}
int main ()
{
int NUM_THREADS;
cout << "Enter the number of threads:\n";
cin >> NUM_THREADS;
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int i;
for( i=0; i < NUM_THREADS; i++ ){
cout <<"main() : creating thread, " << i << endl;
td[i].thread_id = i;
pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
cout << endl << "this line prints every time" << endl;
}
cout << endl << "This line is never printed out";
pthread_exit(NULL);
}
It's because you're not using pthread_join(threads[i],NULL). pthread_join() prevents the main from ending before the threads finish executing
I am trying to make use of boost::thread to perform "n" similar jobs. Of course, "n" in general could be exorbitantly high and so I want to restrict the number of simultaneously running threads to some small number m (say 8). I wrote something like the following, where I open 11 text files, four at a time using four threads.
I have a small class parallel (which upon invoking run() method would open an output file and write a line to it, taking in a int variable. The compilation goes smoothly and the program runs without any warning. The result however is not as expected. The files are created, but they are not always 11 in number. Does anyone know what's the mistake I am making?
Here's parallel.hpp:
#include <fstream>
#include <iostream>
#include <boost/thread.hpp>
class parallel{
public:
int m_start;
parallel()
{ }
// member function
void run(int start=2);
};
The parallel.cpp implementation file is
#include "parallel.hpp"
void parallel::run(int start){
m_start = start;
std::cout << "I am " << m_start << "! Thread # "
<< boost::this_thread::get_id()
<< " work started!" << std::endl;
std::string fname("test-");
std::ostringstream buffer;
buffer << m_start << ".txt";
fname.append(buffer.str());
std::fstream output;
output.open(fname.c_str(), std::ios::out);
output << "Hi, I am " << m_start << std::endl;
output.close();
std::cout << "Thread # "
<< boost::this_thread::get_id()
<< " work finished!" << std::endl;
}
And the main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include "parallel.hpp"
int main(int argc, char* argv[]){
std::cout << "main: startup!" << std::endl;
std::cout << boost::thread::hardware_concurrency() << std::endl;
parallel p;
int populationSize(11), concurrency(3);
// define concurrent thread group
std::vector<boost::shared_ptr<boost::thread> > threads;
// population one-by-one
while(populationSize >= 0) {
// concurrent threads
for(int i = 0; i < concurrency; i++){
// create a thread
boost::shared_ptr<boost::thread>
thread(new boost::thread(¶llel::run, &p, populationSize--));
threads.push_back(thread);
}
// run the threads
for(int i =0; i < concurrency; i++)
threads[i]->join();
threads.clear();
}
return 0;
}
You have a single parallel object with a single m_start member variable, which all threads access without any synchronization.
Update
This race condition seems to be a consequence of a design problem. It is unclear what an object of type parallel is meant to represent.
If it is meant to represent a thread, then one object should be allocated for each thread created. The program as posted has a single object and many threads.
If it is meant to represent a group of threads, then it should not keep data that belongs to individual threads.