I am working on a final project for a class. This project is to mimic multiple atm's. That is my program already runs. Inside of my main.cpp, I created the threads, for now just two, later on maybe more, They call a class Begin that rand() if customers are going to make a deposit or withdraw and then rand() the amount they are going to use and does this 5 times.
#include "ATM.h"
void main()
{
Begin test1;
test1.manager();
thread first(&Begin::atm, test1);
thread second(&Begin::atm, test1);
first.join();
second.join();
delete resbox::cashbox;
system("pause");
}
I cannot figure out how to suspend my threads created in Main.cpp inside of my observe() function like so:
void watcher::observe()
{
float cash;
if (resbox::cashbox->gettotal() >= resbox::cashbox->getmax())
{
//suspend all other threads
cout << "Please empty cash box it is full! with $"<< resbox::cashbox->gettotal() << endl;
cout << "How much would like to withdraw?" << endl;
cin >> cash;
resbox::cashbox->cashwd(cash);
cout << "This is the amount in the reserve box now is $" << resbox::cashbox->gettotal() << endl;
//resume all other threads
}
if (resbox::cashbox->gettotal() <= 500)
{
//suspend all other threads
cout << "Please fill cashbox it is low, has $" << resbox::cashbox->gettotal() << endl;
cout << "How much would like to add?" << endl;
cin >> cash;
resbox::cashbox->cashdp(cash);
cout << "This is the amount in the reserve box now $" << resbox::cashbox->gettotal() << endl;
//resume all other threads
}
}
Whenever the condition is met for one of the if statements I need to be able to suspend all other threads except the current thread that met the condition. Then after the data is completed before leaving the if statement and observer functions resume all other threads.
I read about the possibility of using SuspendThread, and ResumeThread from here, how to suspend thread. Yet I am having a hard time passing the threads created in main.cpp to the observer function so that I could call those functions. I figured out how to create threads from cplusplus.com, I also notice I could potentially use a mutex locking as refered to from What is the best solution to pause and resume pthreads?
I am using c++ under Microsoft Visual Studio 2015 Community.
This is my first time dealing with threads. For my use which is better, pass the created threads to the observer function, or is there another to pause/suspend and then resume them and how would i do so? Thank you for any advice/help provided.
Currently If I run my program and one of the conditions is met by a thread, the other thread will also meet the same condition and I have to enter the amount to deposit/withdraw twice before the threads continue until each thread has dealt with 5 customers each for a total of 10 customers.
I finally figured out what I needed and what to use thanks to:
Class RWLock
By utilizing this class, inside my project. Then creating a global instance of that class.
Then I added the reader and writer lock and unlocks where it function inside my code the best. Like so:
void Begin::atm() //The main function that makes it easier for threads to
call and run the Program.
{
ATM atm;
int choice, amount;
LARGE_INTEGER cicles;
QueryPerformanceCounter(&cicles);
srand(cicles.QuadPart);
for (int i = 0; i < imax; i++) //mimics a total of 5 customers
{
rw.ReadLock(); //Have to place to read lock here.
choice = rand() % 2; //Randomizes the choice of depositing or withdrawing.
amount = rand() % 5000 + 1; //Randomizes 'the amount of cash that the customers use.
rw.ReadUnlock(); //Read unlock must happen here otherwise it blocks the writers.
rw.WriteLock(); //Must happen here!
if (choice == 0)
{
atm.cashdp(amount);
cout << "\tCustomer depositing $" << amount << endl;
}
else if (choice == 1)
{
atm.cashwd(amount);
cout << "\tCustomer withdrawing $" << amount << endl;
}
else
//error checker against the randomizer for the choice of depsoiting or withdrawing.
cout << "error rand creating wrong number" << endl;
rw.WriteUnlock(); //Must Happen here!
Sleep(5000); // Sleeps the program between customer usage to mimic actual use.
}
}
Related
I am trying to understand, then, write some code that has to read from, and write to many different files and do so from the main loop of my application. I am hoping to use the C++11 model present in VS 2013.
I don't want to stall the main loop so I am investigating spinning off a thread each time a request to write or read a file is generated.
I've tried many things including using the async keyword which sounds promising. I boiled down some code to a simple example:
#include <future>
#include <iostream>
#include <string>
bool write_file(const std::string filename)
{
std::cout << "write_file: filename is " << filename << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "write_file: written" << std::endl;
return true;
}
int main(int argc, char* argv[])
{
const std::string filename = "foo.txt";
auto write = std::async(std::launch::async, write_file, filename);
while (true)
{
std::cout << "working..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "write result is " << write.get() << std::endl;
}
}
I'm struggling to understand the basics but my expectation would be that this code would constantly print "working..." and interspersed in the output would be the write_file start and end messages. Instead, I see that the write_file thread seems to block the main loop output until the timer expires.
I realize I need to also consider mutex/locking on the code to actually write the file but I would like to understand this bit first.
Thank you if you can point me in the right direction.
Molly.
write.get() will wait for the async task to finish. You want to use wait_for() instead:
do {
std::cout << "working...\n";
} while(write.wait_for(std::chrono::milliseconds(100)) != std::future_status::ready);
std::cout << "write result is " << write.get() << "\n";
I am using a wrapper function in an external software to start a new thread, which updates a global variable, but yet this seems invisible to the main thread. I cant call join(), not to block the main thread and crash the software. boost::async, boost::thread and boost::packaged_task all behave the same way.
uint32 *Dval;
bool hosttask1()
{
while(*Dval<10)
{
++*Dval;
PlugIn::gResultOut << " within thread global value: " << *Dval << std::endl;
Sleep(500);
}
return false;
}
void SU_HostThread1(uint32 *value)
{
Dval = value;
*Dval = 2;
PlugIn::gResultOut << " before thread: " << *value << " before thread global: " << *Dval << std::endl;
auto myFuture = boost::async(boost::launch::async,&hosttask1);
//boost::thread thread21 = boost::thread(&hosttask1);
//boost::packaged_task<bool> pt(&hosttask1);
//boost::thread thread21 = boost::thread(boost::move(pt));
}
When I call the function:
number a=0
su_hostthread1(a)
sleep(2) //seconds
result(" function returned "+a+" \n")
OUTPUT:
before thread value: 2 before thread global value: 2
within thread global value: 3
within thread global value: 4
within thread global value: 5
within thread global value: 6
function returned 2
within thread global value: 7
within thread global value: 8
within thread global value: 9
within thread global value: 10
Any ideas?
Thanks in advance!
If you share data between threads, you must syncronize access to that data. The two possible ways are a mutex protecting said data and atomic operations. The simple reason is that caches and read/write reordering (both by CPU and compiler) exist. This is a complex topic though and it's nothing that can be explained in an answer here, but there are a few good books out there and also a bunch of code that gets it right.
The following code correctly reproduces what I intend to do. Mainly, the thread updates a global variable which the main thread correctly observes.
#include "stdafx.h"
#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
unsigned long *dataR;
bool hosttask1()
{
bool done = false;
std::cout << "In thread global value: " << *dataR << "\n"; //*value11 << *dataL <<
unsigned long cc = 0;
boost::mutex m;
while (!done)
{
m.lock();
*dataR = cc;
m.unlock();
cc++;
std::cout << "In thread loop global value: "<< *dataR << "\n";
if (cc==5) done = true;
}
return done;
}
void SU_HostThread1(unsigned long *value)
{
dataR = value;
std::cout << "Before thread value: " << *value << " Before thread global value: " << *dataR << "\n"; //*value11 << *dataL <<
auto myFuture = boost::async(boost::launch::async, &hosttask1);
return;
}
int main()
{
unsigned long value =1;
unsigned long *value11;
value11 = &value;
SU_HostThread1(value11);
boost::this_thread::sleep(boost::posix_time::seconds(1));
std::cout << "done with end value: " << *value11 << "\n";
return 0;
}
output:
Before thread value: 1 Before thread global value: 1
In thread global value: 1
In thread loop global value: 0
In thread loop global value: 1
In thread loop global value: 2
In thread loop global value: 3
In thread loop global value: 4
done with end value: 4
Yet when I copy this exactly to the SDK of the external software, the main thread does not update global value. Any ideas how this is so?
Thanks
output in external software:
before thread value: 1 before thread global value: 1
In thread global value: 1
In thread loop global value: 0
In thread loop global value: 1
In thread loop global value: 2
In thread loop global value: 3
In thread loop global value: 4
done with end value: 1
Likely this is because the compiler doesn't generally think about multithreading when optimising your code. If has seen you code checks a value repeatedly, and it knows that in single threading that value cannot change, so it just omitted the check.
If you declare the variable as volatile, then it will probably generate less efficient code that checks more often.
Of course you have to also understand that when a value is written, there are circumstances when it may not all be written in one go, so if you are unlucky enough to read it back when it is half-written, then you get back a garbage value. The fix for that is to declare it as std::atomic (which is automatically considered volatile by the optimiser), and then even more complex code will be emitted to ensure that the write and the read cannot intersect (or different processor primitives might be used for small objects such as integers)
most variables are not shared between threads, and when they are it is up to the programmer to identify those and balance optimisation against the thread synchronisation needs during design.
In the below code, there are two joins (of course one is commented). I would like to know what is the difference between
when join is executed before the loop and when join is executed after the loop?
#include <iostream>
#include <thread>
using namespace std;
void ThreadFunction();
int main()
{
thread ThreadFunctionObj(ThreadFunction);
//ThreadFunctionObj.join();
for (int j=0;j<10;++j)
{
cout << "\tj = " << j << endl;
}
ThreadFunctionObj.join();
return 0;
}
void ThreadFunction()
{
for (int i=0;i<10;++i)
{
cout << "i = " << i << endl;
}
}
A join() on a thread waits for it to finish execution, your code doesn't continue as long as the thread isn't done. As such, calling join() right after starting a new thread defeats the purpose of multi-threading, as it would be the same as executing those two for loops in a serial way. Calling join() after your loop in main() ensures that both for loops execute in parallel, meaning that at the end of your for loop in your main(), you wait for the ThreadFunction() loop to be done too. This is the equivalent of you and a friend going out to eat, for example. You both start eating at relatively the same time, but the first one to finish still has to wait for the other (might not be the best example, but hope it does the job).
Hope it helps
I have very simple code in which multiple threads are trying to insert data in std::map and as per my understanding this should led to program crash because this is data race
std::map<long long,long long> k1map;
void Ktask()
{
for(int i=0;i<1000;i++)
{
long long random_variable = (std::rand())%1000;
std::cout << "Thread ID -> " << std::this_thread::get_id() << " with looping index " << i << std::endl;
k1map.insert(std::make_pair(random_variable, random_variable));
}
}
int main()
{
std::srand((int)std::time(0)); // use current time as seed for random generator
for (int i = 0; i < 1000; ++i)
{
std::thread t(Ktask);
std::cout << "Thread created " << t.get_id() << std::endl;
t.detach();
}
return 0;
}
However i ran it multiple time and there is no application crash and if run same code with pthread and c++03 application is crashing so I am wondering is there some change in c++11 that make map insert thread safe ?
No, std::map::insert is not thread-safe.
There are many reasons why your example may not crash. Your threads may be running in a serial fashion due to the system scheduler, or because they finish very quickly (1000 iterations isn't that much). Your map will fill up quickly (only having 1000 nodes) and therefore later insertions won't actually modify the structure and reduce possibility of crashes. Or perhaps the implementation you're using IS thread-safe.
For most standard library types, the only thread safety guarantee you get is that it is safe to use separate object instances in separate threads. That's it.
And std::map is not one of the exceptions to that rule. An implementation might offer you more of a guarantee, or you could just be getting lucky.
And when it comes to fixing threading bugs, there's only one kind of luck.
Short question:
How can setting the _EM_INVALID exception flag on the FPU result in different values?
Long question:
In our project we have turned off floating point exceptions in our Release build, but turned on ZERODIVIDE, INVALID and OVERFLOW using _controlfp_s() in our Debug build. This is in order to catch errors if they are there.
However, we would also like results of numerical calculations (involving optimisation algorithms, matrix inversion, Monte Carlo and all sorts of things) to be consistent between Debug and Release build to make debugging easier.
I would expect that the setting of the exception flags on the FPU should not affect the calculated values - only whether exceptions are thrown or not. But after working backwards through our calculations I can isolate the below code example that shows that there is a difference on the last bit when calling the log() function.
This propagates to a 0.5% difference in the resulting value.
The below code will give the shown program output when adding it to a new solution in Visual Studio 2005, Windows XP and compile in Debug configuration. (Release will give a different output, but that's because the optimiser reuses the result from the first call to log().)
I hope that someone can shed a bit of light on this. Thanks.
/*
Program output:
Xi, 3893f76f, 7.4555176582633598
K, c0a682c7, 7.44466687218
Untouched
x, da8caea1, 0.0014564635732296288
Invalid exception on
x, da8caea2, 0.001456463573229629
Invalid exception off
x, da8caea1, 0.0014564635732296288
*/
#include <float.h>
#include <math.h>
#include <limits>
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
unsigned uMaskOld = 0;
errno_t err;
cout << std::setprecision (numeric_limits<double>::digits10 + 2);
double Xi = 7.4555176582633598;
double K = 7.44466687218;
double x;
cout << "Xi, " << hex << setw(8) << setfill('0') << *(unsigned*)(&Xi) << ", " << dec << Xi << endl;
cout << "K, " << hex << setw(8) << setfill('0') << *(unsigned*)(&K) << ", " << dec << K << endl;
cout << endl;
cout << "Untouched" << endl;
x = log(Xi/K);
cout << "x, " << hex << setw(8) << setfill('0') << *(unsigned*)(&x) << ", " << dec << x << endl;
cout << endl;
cout << "Invalid exception on" << endl;
::_clearfp();
err = ::_controlfp_s(&uMaskOld, 0, _EM_INVALID);
x = log(Xi/K);
cout << "x, " << hex << setw(8) << setfill('0') << *(unsigned*)(&x) << ", " << dec << x << endl;
cout << endl;
cout << "Invalid exception off" << endl;
::_clearfp();
err = ::_controlfp_s(&uMaskOld, _EM_INVALID, _EM_INVALID);
x = log(Xi/K);
cout << "x, " << hex << setw(8) << setfill('0') << *(unsigned*)(&x) << ", " << dec << x << endl;
cout << endl;
return 0;
}
This is not a complete answer, but it is too long for a comment.
I suggest you isolate the code that does the questionable calculations and put it in a subroutine, preferably in a source module that is compiled separately. Something like:
void foo(void)
{
double Xi = 7.4555176582633598;
double K = 7.44466687218;
double x;
x = log(Xi/K);
…Insert output statements here…
}
Then you would call the routine with different settings:
cout << "Untouched:\n";
foo();
cout << "Invalid exception on:\n";
…Change FP state…
foo();
This guarantees that the same instructions are executed in each case, eliminating the possibility that the compiler has for some reason generated separate code for each sequence. The way you have compiled the code, I suspect it is possible the compiler may have used 80-bit arithmetic in one case and 64-bit arithmetic in another, or may have used 80-bit arithmetic generally but converted some result to 64-bit in one case but not another
Once that is done, you can partition and isolate the code further. E.g., try evaluating Xi/K once before any of the tests, storing that in a double, and passing it to foo as a parameter. The tests whether the log call differs depending on the floating-point state. I suspect that is the case, as it is unlikely the division operation would differ.
Another advantage of isolating the code this way is that you could step through it in the debugger to see exactly where behavior diverges. You could step through it, one instruction at a time, with different floating-point states simultaneously in two windows and examine the results at each step to see exactly where the divergence is. If there is no divergence by the time you reach the log call, you should step through that, too.
Incidental notes:
If you know Xi and K are close to each other, it is better to compute log(Xi/K) as log1p((Xi-K)/K). When Xi and K are close to each other, the subtraction Xi-K is exact (has no error), and the quotient has more useful bits (the 1 that we already knew about and some zero bits following it are gone).
The fact that slight changes in your floating-point environment cause a .5% change in your result implies your calculations are very sensitive to error. This suggests that, even if you make your results reproducible, the errors that necessarily exist in floating-point arithmetic cause your result to be inaccurate. That is, the final error will still exist, it just will not be called to your attention by the difference between two different ways of calculating.
It appears in your C++ implementation that unsigned is four bytes but double is eight bytes. So printing the encoding a double by aliasing it to an unsigned omits half of the bits. Instead, you should convert a pointer to the double to a pointer to const char and print sizeof(double) bytes.