I've been doing pretty basic stuff with std::thread without any particular reason, simply in order to learn it. I thought that the simple example I created, where few threads are operating on the same data, locking each other before doing so, worked just fine, until I realized that every time I run it the returned value is different, while very close to each other, I am pretty sure they should equal each other. Some of the values I have received:
21.692524
21.699258
21.678871
21.705947
21.685744
Am I doing something wrong or maybe there is underlying reason for that behaviour?
#include <string>
#include <iostream>
#include <thread>
#include <math.h>
#include <time.h>
#include <windows.h>
#include <mutex>
using namespace std;
mutex mtx;
mutex mtx2;
int currentValue = 1;
double suma = 0;
int assignPart() {
mtx.lock();
int localValue = currentValue;
currentValue+=10000000;
mtx.unlock();
return localValue;
}
void calculatePart()
{
int value;
double sumaLokalna = 0;
while(currentValue<1500000000){
value = assignPart();
for(double i=value;i<(value+10000000);i++){
sumaLokalna = sumaLokalna + (1/(i));
}
mtx2.lock();
suma+=sumaLokalna;
mtx2.unlock();
sumaLokalna = 0;
}
}
int main()
{
clock_t startTime = clock();
// Constructs the new thread and runs it. Does not block execution.
thread watek(calculatePart);
thread watek2(calculatePart);
thread watek3(calculatePart);
thread watek4(calculatePart);
while(currentValue<1500000000){
Sleep(100);
printf("%-12d %-12lf \n",currentValue, suma);
}
watek.join();
watek2.join();
watek3.join();
watek4.join();
cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " seconds." << endl;
//Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
}
Your loop
while(currentValue<1500000000){
Sleep(100);
printf("%-12d %-12lf \n",currentValue, suma);
}
is printing intermediate results, but you're not printing the final result.
To print the final result, add the line
printf("%-12d %-12lf \n",currentValue, suma);
after joining the threads.
Related
I am new to C++11 and using threading features. In the following program, the main thread starts 9 worker threads and pushes data into a queue and then goes to wait for thread termination. I see that the worker threads don't get woken up and the program just hangs.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>
#include <chrono>
#include <future>
#include <atomic>
using namespace std::chrono_literals;
std::mutex _rmtx;
std::mutex _wmtx;
std::queue<unsigned long long> dataq;
std::condition_variable _rcv;
std::condition_variable _wcv;
std::atomic_bool termthd;
void thdfunc(const int& num)
{
std::cout << "starting thread#" << num << std::endl;
std::unique_lock<std::mutex> rul(_rmtx);
while (true) {
while(!_rcv.wait_until(rul, std::chrono::steady_clock::now() + 10ms, [] {return !dataq.empty() || termthd.load(); }));
if (termthd.load()) {
std::terminate();
}
std::cout<<"thd#" << num << " : " << dataq.front() <<std::endl;
dataq.pop();
_wcv.notify_one();
}
}
int main()
{
std::vector<std::thread*> thdvec;
std::unique_lock<std::mutex> wul(_rmtx);
unsigned long long data = 0ULL;
termthd.store(false);
for (int i = 0; i < 9; i++) {
thdvec.push_back(new std::thread(thdfunc, i));
}
for ( data = 0ULL; data < 2ULL; data++) {
_wcv.wait_until(wul, std::chrono::steady_clock::now() + 10ms, [&] {return data > 1000000ULL; });
dataq.push(std::ref(data));
_rcv.notify_one();
}
termthd.store(true);
_rcv.notify_all();
//std::this_thread::yield();
for (int i = 0; i < 9; i++) {
thdvec[i]->join();
}
}
I am unable to figure out the problem. How can I make sure the threads get woken up and processes the requests and terminates normally?
This std::unique_lock<std::mutex> wul(_rmtx); will lock the _rmtx mutex until the end of main scope. It's surely an issue, because other threads trying to get the lock on _rmtx will block:
int main()
{
std::vector<std::thread*> thdvec;
std::unique_lock<std::mutex> wul(_rmtx); // <- locking mutex until end of main.
// other threads trying to lock _rmtx will block
unsigned long long data = 0ULL;
// ... rest of the code ...
#include <iostream>
#include<thread>
#include <initializer_list>
#include <vector>
#include <future>
#include <time.h>
using namespace std;
class Gadget{
public:
Gadget(){
flag_ = false;
cout<<"Creating new Gadgets"<<endl;
}
void wait(){
while(flag_==false){
cout<<"waiting here...."<<endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
void wake(){
flag_ = true;
}
private:
volatile bool flag_;
};
I am trying to make two threads and one thread will sleep for 1 sec after checking the flag value. As i have made flag volatile it should change at some point. But the program is waiting infinitely.
int main() {
Gadget g;
thread t(&Gadget::wait,g);
thread s(&Gadget::wake,g);
t.join();
s.join();
cout<<"Ending the program "<<endl;
return 0;
}
volatile isn't for variables that are changed by the program itself. It's for variables that changes outside the program's control - like if it's directly connected to hardware.
Your main problem is however that you pass g by value so the two threads are working on different copies of your original g.
So, change to
std::atomic<bool> flag_;
and
thread t(&Gadget::wait, &g);
thread s(&Gadget::wake, &g);
Also worth mentioning: The two methods will not necessarily run in the order you start them, so waiting here.... may or may not show up.
Edit:
As mentioned in the comments: When waiting for a condition you should usually use a std::condition_variable. I've made an example of how that could look. I've also moved the starting of the threads into Gadget which makes it more obvious which object the thread is working on.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
class Gadget {
public:
Gadget() { std::cout << "Creating new Gadget\n"; }
// new interface for starting threads
std::thread start_wait() { return std::thread(&Gadget::wait, this); }
std::thread start_wake() { return std::thread(&Gadget::wake, this); }
private:
void wait() {
std::unique_lock<std::mutex> ul(mutex_);
std::cout << "wait: waiting here...\n";
// Read about "spurious wakeup" to understand the below:
while(not flag_) cond_.wait(ul);
// or:
// cond_.wait(ul, [this] { return flag_; });
std::cout << "wait: done\n";
}
void wake() {
// simulate some work being done for awhile
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
{ // lock context start
std::lock_guard<std::mutex> lg(mutex_);
flag_ = true;
std::cout << "wake: notifying the waiting threads\n";
} // lock context end
// notify all waiting threads
cond_.notify_all();
}
std::condition_variable cond_;
std::mutex mutex_;
bool flag_ = false; // now guarded by a mutex instead
};
int main() {
Gadget g;
// start some waiting threads
std::vector<std::thread> threads(16);
for(auto& th : threads) th = g.start_wait();
// and one that wakes them up
auto th_wake = g.start_wake();
for(auto& th : threads) th.join();
th_wake.join();
std::cout << "Ending the program\n";
}
I would like to measure the execution time of some code. The code starts in the main() function and finishes in an event handler.
I have a C++11 code that looks like this:
#include <iostream>
#include <time.h>
...
volatile clock_t t;
void EventHandler()
{
// when this function called is the end of the part that I want to measure
t = clock() - t;
std::cout << "time in seconds: " << ((float)t)/CLOCKS_PER_SEC;
}
int main()
{
MyClass* instance = new MyClass(EventHandler); // this function starts a new std::thread
instance->start(...); // this function only passes some data to the thread working data, later the thread will call EventHandler()
t = clock();
return 0;
}
So it is guaranteed that the EventHandler() will be called only once, and only after an instance->start() call.
It is working, this code give me some output, but it is a horrible code, it uses global variable and different threads access global variable. However I can't change the used API (the constructor, the way the thread calls to EventHandler).
I would like to ask if a better solution exists.
Thank you.
Global variable is unavoidable, as long as MyClass expects a plain function and there's no way to pass some context pointer along with the function...
You could write the code in a slightly more tidy way, though:
#include <future>
#include <thread>
#include <chrono>
#include <iostream>
struct MyClass
{
typedef void (CallbackFunc)();
constexpr explicit MyClass(CallbackFunc* handler)
: m_handler(handler)
{
}
void Start()
{
std::thread(&MyClass::ThreadFunc, this).detach();
}
private:
void ThreadFunc()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
m_handler();
}
CallbackFunc* m_handler;
};
std::promise<std::chrono::time_point<std::chrono::high_resolution_clock>> gEndTime;
void EventHandler()
{
gEndTime.set_value(std::chrono::high_resolution_clock::now());
}
int main()
{
MyClass task(EventHandler);
auto trigger = gEndTime.get_future();
auto startTime = std::chrono::high_resolution_clock::now();
task.Start();
trigger.wait();
std::chrono::duration<double> diff = trigger.get() - startTime;
std::cout << "Duration = " << diff.count() << " secs." << std::endl;
return 0;
}
clock() call will not filter out executions of different processes and threads run by scheduler in parallel with program event handler thread. There are alternative like times() and getrusage() which tells cpu time of process. Though it is not clearly mentioned about thread behaviour for these calls but if it is Linux, threads are treated as processes but it has to be investigated.
clock() is the wrong tool here, because it does not count the time actually required by the CPU to run your operation, for example, if the thread is not running at all, the time is still counted.
Instead you have to use platform-specific APIs, such as pthread_getcpuclockid for POSIX-compliant systems (Check if _POSIX_THREAD_CPUTIME is defined), that counts the actual time spent by a specific thread.
You can take a look at a benchmarking library I wrote for C++ that supports thread-aware measuring (see struct thread_clock implementation).
Or, you can use the code snippet from the man page:
/* Link with "-lrt" */
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
thread_start(void *arg)
{
printf("Subthread starting infinite loop\n");
for (;;)
continue;
}
static void
pclock(char *msg, clockid_t cid)
{
struct timespec ts;
printf("%s", msg);
if (clock_gettime(cid, &ts) == -1)
handle_error("clock_gettime");
printf("%4ld.%03ld\n", ts.tv_sec, ts.tv_nsec / 1000000);
}
int
main(int argc, char *argv[])
{
pthread_t thread;
clockid_t cid;
int j, s;
s = pthread_create(&thread, NULL, thread_start, NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
printf("Main thread sleeping\n");
sleep(1);
printf("Main thread consuming some CPU time...\n");
for (j = 0; j < 2000000; j++)
getppid();
pclock("Process total CPU time: ", CLOCK_PROCESS_CPUTIME_ID);
s = pthread_getcpuclockid(pthread_self(), &cid);
if (s != 0)
handle_error_en(s, "pthread_getcpuclockid");
pclock("Main thread CPU time: ", cid);
/* The preceding 4 lines of code could have been replaced by:
pclock("Main thread CPU time: ", CLOCK_THREAD_CPUTIME_ID); */
s = pthread_getcpuclockid(thread, &cid);
if (s != 0)
handle_error_en(s, "pthread_getcpuclockid");
pclock("Subthread CPU time: 1 ", cid);
exit(EXIT_SUCCESS); /* Terminates both threads */
}
Here is my simple code, I want to get in the console_task, the value of the variable i in the dialer_task... without using a global variable.
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <thread>
#include "console.hpp"
using namespace std;
void console_task(){
console();
}
void dialer_task(){
int i=0;
while (1) {
printf("LOOP %d\n",i);
i++;
sleep(5);
}
}
int main()
{
thread t1(console_task);
thread t2(dialer_task);
t1.join();
t2.join();
return 0;
}
The constraint that there may not be a global variable to share the state between the threads leaves essentially 2 viable alternatives;
Allocate the shared state on the heap and pass that on to the threads
Allocate the shared state on the original thread's stack and "feed" it to the worker threads for shared use.
The catch to both solutions is to make sure that the access is appropriately guarded or atomic.
A simple solution is to use an std::atomic and share the reference between the threads.
#include <type_traits>
#include <thread>
#include <atomic>
#include <iostream>
void console_task(std::atomic_int& j) {
using namespace std;
int i = 0;
while (++i < 50) {
cout << "task " << j << endl; // uncontrolled access to the console (demo)
std::chrono::microseconds delay{50};
this_thread::sleep_for(delay);
}
}
void dialer_task(std::atomic_int& j){
using namespace std;
int i = 0;
while ( ++i < 10) {
//cout << "LOOP " << i << endl; // uncontrolled access to the console (demo)
std::chrono::microseconds delay{145};
this_thread::sleep_for(delay);
j = i;
}
}
int main()
{
std::atomic_int i { 0 };
std::thread t1( console_task, std::ref(i));
// a lambda with reference capture could also be used
// std::thread t1( [&](){console_task(i);} );
std::thread t2( dialer_task, std::ref(i));
t1.join();
t2.join();
return 0;
}
There is a catch to the shared atomic, it needs to remain valid for the duration of the threads (as it does here).
Demo code.
Further heap based alternatives can be considered; e.g. using a shared std::mutex together with a std::shared_ptr.
I am trying mutex lock with independent threads. The requirement is, I have many threads which will run independently and access/update a common recourse. To ensure that the recourse is updated via a single task, I used mutex. However this is not working.
I have pasted code, a representation of what I am trying to do below:
#include <iostream>
#include <map>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <unistd.h>
std::mutex mt;
static int iMem = 0;
int maxITr = 1000;
void renum()
{
// Ensure that only 1 task will update the variable
mt.lock();
int tmpMem = iMem;
usleep(100); // Make the system sleep/induce delay
iMem = tmpMem + 1;
mt.unlock();
printf("iMem = %d\n", iMem);
}
int main()
{
for (int i = 0; i < maxITr; i++) {
std::thread mth(renum);
mth.detach(); // Run each task in an independent thread
}
return 0;
}
but this is terminating with the below error:
terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable
I want to know if the usage of <thread>.detach() is correct above? If I use .join() it works, but I want each thread to run independently and not wait for the thread to finish.
I also want to know what is the best way to achieve the above logic.
Try this:
int main()
{
std::vector<std::thread> mths;
mths.reserve(maxITr);
for (int i = 0; i < maxITr; i++) {
mths.emplace_back(renum);
}
for (auto& mth : mths) {
mth.join();
}
}
This way, you retain control of the threads (by not calling detach()), and you can join them all at the end, so you know they have completed their tasks.