C++: Changing global variable in multiple threads - c++

I don't really know much about threads in c++. Here is a simple code:
int a = 0;
int main()
{
std::thread t1([=]() {
for (int i = 0; i < 10; i++)
{
a += 1;
std::cout << "A in another thread: " << a << std::endl;
}
});
for (int i = 0; i < 10; i++)
{
a += 1;
std::cout << "A in main: " << a << std::endl;
}
}
When I run this code it gives me a Debug Error: abort() has been called.
How can I change a global variable's value on multiple threads?

because you didn't joined thread after your programme finished. OS will send SIGABRT to detached thread to avoid this problem you should join the thread.
you should put below line at end of main:
t1.join()
Note: beware about possible race condition on variable a.

You have 2 issues:
First of all when you start another thread you have to join it or detach before the program terminates.
Second thing is that you can read the same variable from many threads, but writing to it creates race condition.

Related

Unable to create real multithreading in C++ (using for loop)

I am new to C++ and I am trying to create multiple threads using for loop. Here is the code
#include <iostream>
#include <thread>
class Threader{
public:
int foo(int z){
std::cout << "Calling this function with value :" << z << std::endl;
return 0;
}
};
int main()
{
Threader *m;
std::cout << "Hello world!" << std::endl;
std::thread t1;
for(int i = 0; i < 5; i++){
std::thread t1(&Threader::foo, m, i);
t1.join();
}
return 0;
}
This is the output
As you can see the function I am calling is being invoked using Thread 5 times, but I have to do a t1.join inside the for loop. Without the join the for loop fails in the very first iteration. Like shown here
But if I use the join(), then the threads are being created and executed sequentially cause join() waits for each thread completion. I could easily achieve Actual multithreading in Java by creating Threads in a loop using runnable methods.
How can I create 5 threads which would run absolutely parallel in C++?

Run methods in new process and wait for them to finish

I need my app to be able to run some methods under a new process, and ideally be able to get a return value from those methods however I have not yet found how I can do this (my C++ knowledge is pretty basic).
So to explain better, let's say I have methods A, A1 and A2. Method A will start executing and at some point it will:
Run method A1 under a new process
Wait for A1 to complete and possibly get return value
Run method A2 under another new process
Wait for A2 to complete and again get return value
Continue running code under original process
I found that I can use fork() to run code in a subprocess, however this does not suit my needs because it seems to be creating a copy of the parent process and not just running the specific code I want only in the new process. Here is an excerpt of what I tried, I'm not sure if it can be modified to do what I want it to or if I should use something else completely:
int main(){
std::cout << "START" << std::endl;
test1();
test2();
std::cout << "FINISH" << std::endl;
return 0;
}
void test1(){
pid_t pid = fork();
if (pid == 0){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 1 " << std::endl;
}
}
}
void test2(){
pid_t pid = fork();
if (pid == 0){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 2 " << std::endl;
}
}
}
This however results in test2() being executed twice, and FINISH printed 4 times since the parent process is copied to the subprocess.
I am doing this on Linux at the moment, although I'll need to do the same for Windows eventually.
First of all your parent process should wait for the child processes to exit.
Then your child process should exit once they're done, or else the functions will return on both the child and parent processes.
It sound to me like multi-threading might be the best option for you. This way you share the same memory space and can easily get return values. Look into using OpenMP. I think it is by far the easiest way to multi thread. You can launch tasks for each of the function in a parallel block.
int main(){
std::cout << "START" << std::endl;
int ret1, ret2;
#pragma omp parallel
{
#pragma omp task
ret1 = test1();
#pragma omp task
ret2 = test2();
} //blocks at end of parallel block to wait for tasks to finish
std::cout << "FINISH" << std::endl;
return 0;
}
int test1(){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 1 " << std::endl;
}
return 0;
}
int test2(){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 2 " << std::endl;
}
return 0;
}
I modified the code in my browser so I can not guarantee it compiles but this is how you can launch functions in parallel and get a return value. I do not think forking is the best way to go about it since you would then need some sort of interprocess communication to get data back. Also OpenMP is probably much more efficient. You could also look into using PThreads which is what I think OpenMP uses on the backed but that is more complicated. Also if you are using C++11 look into using std::async(...) which can spawn threads for functions.

C++ detached thread continues to work after its associated object was deleted

In a scope I create an object, which contains a thread. The thread is detached in object c-tor. Finally I delete the object, but the thread keeps continuing, after the associated object memory was freed. Does the detached thread saves the objects copy or it only reference to the program stack, which will be erased further on?
struct test_detach {
test_detach()
: thr_(&test_detach::loop, this) {
thr_.detach();
}
void loop() {
while(true) {
cout << "loop test" << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
std::thread thr_;
};
int main()
{
{
test_detach *test = new test_detach;
std::this_thread::sleep_for(std::chrono::seconds(1));
delete test;
}
cout << "Sleep" << endl;;
std::this_thread::sleep_for(std::chrono::seconds(3));
cout << "Finish!" << endl;;
return 0;
}
The program output:
loop test
loop test
Sleep
loop test
loop test
loop test
loop test
loop test
loop test
Finish!
Well the thread keeps on going until the program is terminated. Your thread doesn't use any data fields of the particular test_detach structure, so there is no SEGFAULT. If you however add a member variable to the structure and attempt to access it from the detached thread after the structure was deleted from the main thread it might cause a SEGFAULT / undefined behaviour etc. The test_detach structure is located on the heap. It is not copied anywhere, that is sort of the point. However:
void loop() {
int x = 0;
while(true) {
cout << "loop test, x: " << x++ << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
will work correctly since x is on the stack which is maintained for the particular thread.

Why string variable print with garbage

I wrote the following simple program to understand threads. In the result there are some garbage characters - why are these characters appearing? I'm using GNU G++ compiler in Fedora 17.
#include <iostream>
#include <string.h>
#define THREAD_COUNT 5
struct Man
{
char name[10];
int age;
std::string address;
};
void* ThreadTask(void* man)
{
Man *my_man = (Man*)man;
std::cout << "Address of the person: " << my_man->address << std::endl;
}
int main()
{
pthread_t threads[THREAD_COUNT];
Man men_list[THREAD_COUNT];
for(int i=0; i<THREAD_COUNT; i++)
{
strcpy(men_list[i].name,"nayana");
men_list[i].age = i;
men_list[i].address = "Singapore";
int rc = pthread_create(&threads[i],NULL,ThreadTask,(void*)&men_list[i]);
if(rc)
{
std::cout << "Error while creating the thread" << std::endl;
}
}
pthread_exit(NULL);
return 0;
}
Result:
Address of the person: Singapore�0+���*��! ����Singapore�0��▒s�!��t��s���E��t��s���EI
Address of the person: Singapore�0;s��:s�!�w ����Singapore�0+���*��! ����Singapore�0��▒s�!��t��s���E��t��s���EI
Address of the person: Address of the person:
You need to ensure that all the threads run before men_list goes out of scope and the memory is reclaimed.
This is not what pthread_exit does -- rather it terminates the calling thread.
The pthread_exit(NULL) at the end of your main() is not accomplishing anything sensible. Even though the man page says that exiting the main function with pthread_exit will "allow other threads to run to completion" (as you refer to in the comments), this doesn't mean that the scope of the main function won't end when the function does, nor does it mean that the other threads will run to completion before pthread_exit returns.
You can use pthread_join to wait for a thread to run to completion. To wait for all your threads to run to completion, you could use something like this:
int main()
{
pthread_t threads[THREAD_COUNT];
Man men_list[THREAD_COUNT];
for(int i=0; i<THREAD_COUNT; i++)
{
strcpy(men_list[i].name,"nayana");
men_list[i].age = i;
men_list[i].address = "Singapore";
int rc = pthread_create(&threads[i],NULL,ThreadTask,(void*)&men_list[i]);
if(rc)
{
std::cout << "Error while creating the thread" << std::endl;
}
}
for(int i=0; i < THREAD_COUNT; i++)
{
pthread_join( threads[i], NULL );
}
return 0;
}
Also I see synchronization issue. You need to synchronize the common resource whenever you are using threads. Here common resource is std::cout. one way could be put the printing code under some synchronization object. then you will have everything printed in order.

Still having race condition with boost::mutex

I am trying an example, which causes race condition to apply the mutex. However, even with the mutex, it still happens. What's wrong? Here is my code:
#include <iostream>
#include <boost/thread.hpp>
#include <vector>
using namespace std;
class Soldier
{
private:
boost::thread m_Thread;
public:
static int count , moneySpent;
static boost::mutex soldierMutex;
Soldier(){}
void start(int cost)
{
m_Thread = boost::thread(&Soldier::process, this,cost);
}
void process(int cost)
{
{
boost::mutex::scoped_lock lock(soldierMutex);
//soldierMutex.lock();
int tmp = count;
++tmp;
count = tmp;
tmp = moneySpent;
tmp += cost;
moneySpent = tmp;
// soldierMutex.unlock();
}
}
void join()
{
m_Thread.join();
}
};
int Soldier::count, Soldier::moneySpent;
boost::mutex Soldier::soldierMutex;
int main()
{
Soldier s1,s2,s3;
s1.start(20);
s2.start(30);
s3.start(40);
s1.join();
s2.join();
s3.join();
for (int i = 0; i < 100; ++i)
{
Soldier s;
s.start(30);
}
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
}
It looks like you're not waiting for the threads started in the loop to finish. Change the loop to:
for (int i = 0; i < 100; ++i)
{
Soldier s;
s.start(30);
s.join();
}
edit to explain further
The problem you saw was that the values printed out were wrong, so you assumed there was a race condition in the threads. The race in fact was when you printed the values - they were printed while not all the threads had a chance to execute
Based on this and your previous post (were it does not seem you have read all the answers yet). What you are looking for is some form of synchronization point to prevent the main() thread from exiting the application (because when the main thread exits the application all the children thread die).
This is why you call join() all the time to prevent the main() thread from exiting until the thread has exited. As a result of your usage though your loop of threads is not parallel and each thread is run in sequence to completion (so no real point in using the thread).
Note: join() like in Java waits for the thread to complete. It does not start the thread.
A quick look at the boost documentation suggests what you are looking for is a thread group which will allow you to wait for all threads in the group to complete before exiting.
//No compiler so this is untested.
// But it should look something like this.
// Note 2: I have not used boost::threads much.
int main()
{
boost::thread_group group;
boost::ptr_vector<boost::thread> threads;
for(int loop = 0; loop < 100; ++loop)
{
// Create an object.
// With the function to make it start. Store the thread in a vector
threads.push_back(new boost::thread(<Function To Call>));
// Add the thread to the group.
group.add(threads.back());
}
// Make sure main does not exit before all the threads have completed.
group.join_all();
}
If we go back to your example and retrofit your Soldier class:
int main()
{
boost::thread batallion;
// Make all the soldiers part of a group.
// When you start the thread make the thread join the group.
Soldier s1(batallion);
Soldier s2(batallion);
Soldier s3(batallion);
s1.start(20);
s2.start(30);
s3.start(40);
// Create 100 soldiers outside the loo
std::vector<Soldier> lotsOfSoldiers;
lotsOfSoldiers.reserve(100); // to prevent reallocation in the loop.
// Because you are using objects we need to
// prevent copying of them after the thread starts.
for (int i = 0; i < 100; ++i)
{
lotsOfSoldiers.push_back(Solder(batallion));
lotsOfSoldiers.back().start(30);
}
// Print out values while threads are still running
// Note you may get here before any thread.
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
batallion.join_all();
// Print out values when all threads are finished.
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
}