Locking a thread function using Monitor::Enter Monitor::Exit - multithreading

I have a thread class with two functions:
using namespace System::Threading;
public ref class SecThr
{
public:
int j;
void wralot()
{
for (int i=0; i<=400000;i++)
{
j=i;
if ((i%10000)==0)
Console::WriteLine(j);
}
}
void setalot()
{
Monitor::Enter(this);
for (int i=0; i<=400000;i++)
{
j=7;
}
Monitor::Exit(this);
}
};
int main(array<System::String ^> ^args)
{
Console::WriteLine("Hello!");
SecThr^ thrcl=gcnew SecThr;
Thread^ o1=gcnew Thread(gcnew ThreadStart(thrcl, &SecThr::wralot));
Thread^ o2=gcnew Thread(gcnew ThreadStart(thrcl, &SecThr::setalot));
o2->Start();
o1->Start();
o1->Join();
o2->Join();
So, for locking "setalot" function i've used MOnitor::Enter-Exit block. But the output is like i'm running only one thread with function "wralot"
0
10000
20000
30000
40000
7 //here's "setalot" func
60000
e t.c.
Why all the output data is not changed to const (7) by "setalot" func

I think you've misunderstood what Monitor::Enter does. It's only a cooperative lock - and as wralot doesn't try to obtain the lock at all, the actions of setalot don't affect it. It's not really clear why you expected to get a constant output of 7 due to setalot - if wralot did try to obtain the lock, it would just mean that one of them would "win" and the other would have to wait. If wralot had to wait, there'd be no output while setalot was running, and then wralot would go do its thing - including setting j to i on every iteration.
So basically, both threads are starting, and setalot very quickly sets j to 7 a lot of times... that's likely to complete in the twinkling of an eye in computer terms, compared with a Console.WriteLine call. I suggest you add a call to Console::WriteLine at the end of setalot so you can see when it's finished. Obviously after that, it's completely irrelevant - which is why you're seeing 60000, 70000 etc.

Related

Block multiple threads around an atomic variable. conditional_variable or something else?

I am attempting to design a system in which I'll have multiple threads. All these threads share a common variable (which is atomic) at a time and when each thread starts it increments that variable and before that thread ends it decrements that variable. I would like a thread to block if the current value of that variable is greater than a specific limit value. A simple psuedocode is this:
std::atomic<int> var;
int limit = 3; //limit value
void doWork() //This method is run as multiple thread simultaneously
{
if(var.load() < limit)
{
//block until this condition is met
}
//increment
var++;
//Do some work
.....
//Decrement before leaving
var--
}
Now two approaches come to my mind. The first approach is to sleep while var.load < limit but this looks sub-optimal. The second approach is to use conditional_variable. I am using that approach below but I believe I have two issues here
The first thread will block on cv.wait(lk, []{return var.load() <
limit});
Multiple threads wont be doing work only one will do work
while others will be blocked.
I would appreciate it if someone can suggest on how I can remove these defects from the code below or if there is a better approach ?
std::condition_variable cv;
std::mutex cv_m;
std::atomic<int> var;
int limit = 3; //limit value
void doWork()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cerr << "Waiting... \n";
cv.wait(lk, []{
return var.load() < limit
});
//Increment var
var++;
//Do some Work
...
//Decrement Work
var--
cv.notify_all();
}

Do I need a mutex on a vector of pointers?

Here is a simplified version of my situation:
void AppendToVector(std::vector<int>* my_vector) {
for (int i = 0; i < 100; i++) {
my_vector->push_back(i);
}
}
void CreateVectors(const int num_threads) {
std::vector<std::vector<int>* > my_vector_of_pointers(10);
ThreadPool pool(num_threads);
for (for int i = 0; i < 10; i++) {
my_vector_of_pointers[i] = new std::vector<int>();
pool.AddTask(AppendToVector,
&my_vector_of_pointers[i]);
}
}
My question is whether I need to put a mutex lock in AppendToVector when running this with multiple threads? My intuition tells me I do not have to because there is no possibility of two threads accessing the same data, but I am not fully confident.
Every thread is appending different std::vector (inside AppendToVector function) so there is no need for locking in your case. In case you change your code in the way more than one thread access same vector then you will need lock. Don't be confused because std::vectors you are passing to AppendToVector are them-selfs elements of main std::list, it matters only that here threads are manipulating with completely different (not shared) memory

Concurrency in a D program

I am trying to write a simple D program with two threads (main and one spawned in main) with a daughter thread receiving message from the parent thread. Here is my piece:
import std.stdio;
import core.thread;
import std.concurrency;
import std.c.stdio;
extern (C) int kbhit();
void readSignal(){
for(;;){
bool stop = receiveOnly!bool();
if(!stop)
writeln("reading signal...");
else
writeln("stop reading signal...");
Thread.getThis.sleep(1.seconds);
}
}
int main()
{
auto reader = spawn(&readSignal);
bool stop = false;
while(true){
if(kbhit()){
stop = true;
}
option 1: reader.send(stop);
option 2: send(reader, stop);
}
}
return 0;
}
Basically I wait for a keyboard hit and the intend to pause the spawned thread.
Neither of options (option 1 by Andrei Alexandrescu and option 2 as in dlang docs) work for me. What do i do wrong?
It looks to me that your main thread is spinning very hard, sending thousands and thousands of messages to the reader. The reader, however, is only reading one per second. The 'true' message is backed up behind a massive number of 'false' messages.
For a situation like this, you may be better off using a shared variable, rather than using messages. Both threads will be able to safely read and write from it.
as mentioned you are flooding the client thread.
Try adding a sleep like this
Thread.sleep(dur!"msecs"(1500));
As mentioned by duselbaer and Anders S, in your example, the number of sends is huge, but the number of receives is limited by the sleep. So, when the thread should actually get a true, it is already preceded by an overwhelming number of falses in the queue.
Generally, if the child thread is able to receive faster than the parent thread sends, it's fine. Here is a working example produced from your code. The sleep calls may be substituted by doing some work, but the relation must generally hold.
import std.stdio;
import core.thread;
import std.concurrency;
import core.stdc.stdio;
extern (C) int kbhit();
void readSignal() {
for(int i = 0; ; i++) {
bool stop = receiveOnly!bool();
if(!stop)
writeln("reading signal... ", i);
else
{
writeln("stop reading signal...");
break;
}
Thread.getThis.sleep(1.msecs); // this should be no more than below
}
}
int main() {
auto reader = spawn(&readSignal);
bool stop = false;
while(!stop) {
if(kbhit()) {
stop = true;
}
send(reader, stop); // option 1
// reader.send(stop); // option 2 does the same thing as above via UFCS
Thread.getThis.sleep(1.msecs); // this should be no less than above
}
return 0;
}

boost::thread execution

I have a class ChunkManager that has a few (supposed to be) asynchronous methods. These methods handle tasks in my game engine such as loading the map blocks (similar to Minecraft) on a different thread so as not to completely halt the main thread (they are lengthy operations)
Here is one of those methods:
void ChunkManager::asyncRenderChunks(){
boost::thread loadingThread(&ChunkManager::renderChunks,this);
}
Where renderChunks looks like:
void ChunkManager::renderChunks(){
activeChunksMutex->lock();
for(int z=0; z < CHUNK_MAX; z=z+1)
{
for(int y=0; y < CHUNK_MAX; y=y+1)
{
for(int x=0; x < CHUNK_MAX; x=x+1)
{
activeChunks[x][y][z]->Render(scnMgr);
}
}
}
activeChunksMutex->unlock();
}
This should work, right? However it crashes when this runs. I have a feeling it has to do with what I do with the thread after it's created, because if I put
loadingThread.join();
in the aforementioned method, it works fine, but the main thread is halted because obviously its just waiting for the new thread to finish, effectively bringing me back to square one.
Any advice?
Sorry if this is a retarded question, I am new to the concept of threads.
Thanks.
Update (4/9/2013):
I found this gem: http://threadpool.sourceforge.net/
..and solved my problem!
If you can join the thread, it must be joinable.
As it says in the documentation:
When the boost::thread object that represents a thread of execution is destroyed the program terminates if the thread is joinable.
You created a local thread object and immediately let it go out of scope: it is destroyed when ChunkManager::asyncRenderChunks returns.
Either:
make it a detached (non-joinable) thread
void ChunkManager::asyncRenderChunks() {
boost::thread loadingThread(&ChunkManager::renderChunks,this);
loadingThread.detach();
}
or create the thread object elsewhere and keep it alive
class ChunkManager {
boost::thread renderingThread;
bool renderChunkWork; // work to do flag
Chunk activeChunks[CHUNK_MAX][CHUNK_MAX][CHUNK_MAX];
boost::mutex activeChunksMutex;
boost::condition_variable activeChunksCV;
bool shutdown; // shutdown flag
void renderChunks() {
for(int z=0; z < CHUNK_MAX; ++z)
for(int y=0; y < CHUNK_MAX; ++y)
for(int x=0; x < CHUNK_MAX; ++x)
activeChunks[x][y][z]->Render(scnMgr);
}
void renderChunkThread() {
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
while (true) {
while (!(renderChunkWork || shutdown))
activeChunksCV.wait(guard);
if (shutdown)
break;
renderChunks();
doRenderChunks = false;
}
}
public:
ChunkManager()
: loadingThread(&ChunkManager::renderChunkThread, this),
renderChunkWork(false), shutdown(false)
{}
~ChunkManager() {
{ // tell the rendering thread to quit
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
renderChunkShutdown = true;
activeChunksCV.notify_one();
}
renderingThread.join()
}
void asyncRenderChunks() {
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
if (!renderChunkWork) {
renderChunkWork = true;
activeChunksCV.notify_one();
}
}
};
NB. In general, creating threads on-the-fly is less good than creating your threads up-front, and just waking them when there's something to do. It avoids figuring out how to handle a second call to asyncRenderChunks before the last one is complete (start a second thread? block?), and moves the latency associated with thread creation.
Note on object lifetime
It's important to realise that in this code:
void ChunkManager::asyncRenderChunks() {
SomeType myObject;
}
the instance myObject will be created and then immediately destroyed.
It crashes, because in the current version of Boost.Thread, you have to either join() a thread or detach() it - otherwise ~thread would terminate the program. (In earlier versions ~thread used to call detach() automatically.)
So if you don't want to join the thread - just detach it:
boost::thread loadingThread(&ChunkManager::renderChunks,this);
loadingThread.detach();

Invoke Windows Form Thread and Sleeping

I have a managed c++ application that I start a new thread to do some stuff and update some text boxes, it loops and sleeps at the end of every loop. Because of it sleeping I needed to have it in a new thread so the UI doesn't crash. Then I realized I need to invoke the thread that created the UI to access the textboxes, but now I'm back in the main thread so the sleeping crashes it. How should I approach this.
private: System::Void buttonStartCamera_Click(System::Object^ sender, System::EventArgs^ e)
{
ThreadStart^ threadStart = gcnew ThreadStart(this, &UserInterface::SetText);
Thread^ newThread = gcnew Thread(threadStart);
newThread->Start();
}
void SetText()
{
if (this->textBoxCameraOneX->InvokeRequired)
{
MyDel^ del = gcnew MyDel(this, &UserInterface::SetText);
this->Invoke(del);
}
else
{
int count = 0;
srand (time(NULL));
for (count = 0; count < 20; ++count)
{
for each (Camera^ camera in cameraList)
{
textBoxCameraOneX->Text = count.ToString();
}
Sleep(300);
}
}
}
The best option is likely to refactor this so your Sleep doesn't occur within the SetText method. Your background thread could use a separate method that performs the sleep, and then invokes the proper method to set the text (for one text box at a time) in a loop.
In general, you should keep the methods you use with Control::Invoke as short as possible - they should only include the logic required for your UI work, and not the other functionality.
That being said, in this case, it seems like a System::Windows::Forms::Timer would be more appropriate. You could set the interval to 300, and update a text box one at a time in the timer's Tick event.

Resources