How to get the correct thread id and value - c++

I am trying to send vector as data to pthread. But when I am trying to print the thread id , its coming garbage value.
If I run this code with single thread, it works fine. But when I run it with 2 threads, its not working.
#include <iostream>
#include <pthread.h>
#include <vector>
using namespace std;
struct val {
int data;
int sData;
};
void *foo(void *a)
{
vector <val>* b = (vector <val>*)a;
for (val it : *b) {
std::cout <<" thread " <<it.data;
std::cout <<" &&& " <<it.sData<<"-----------"<<endl;
}
}
int main()
{
pthread_t thr[2];
for (int j = 0; j < 2; j++) {
std::vector <val> *a = new std::vector<val>(10);
for (int i = 0; i< 10; i++) {
val t;
t.data = j;
t.sData = j*10;
a->push_back(t);
}
pthread_create(&thr[j], NULL, &foo, &a);
}
pthread_join(thr[0],NULL);
pthread_join(thr[1],NULL);
return 0;
}
Expected Output:
thread 0 &&& 0
....
....
thread 1 &&& 10
thread 1 &&& 10
....
....

You are giving the thread a pointer to a local variable. That variable is destroyed immediately afterwards, at the closing brace of the loop. foo ends up accessing a dangling pointer, whereupon your program exhibits undefined behavior.

Related

How to delay Destructor call in a loop

// Online C++ compiler to run C++ program online
#include <iostream>
#include <iterator>
#include <set>
int index;
int member[5] = {0,1,2,3,4};
class Animal{
public:
Animal(int val){
member[val]=-1;
}
~Animal(){
member[index]=index;
}
};
int main() {
// Write C++ code here
for(int i=0;i<5;i++){
std::cout<<member[i]<<" ";
}
std::cout<<std::endl;
for(int i=0;i<5;i++){
index=i;
Animal a(i);
}
for(int i=0;i<5;i++){
std::cout<<member[i]<<" ";
}
return 0;
}
In following code the output is:
0 1 2 3 4
0 1 2 3 4
But I am interested in the following output:
0 1 2 3 4
-1 -1 -1 -1 -1
So every time we perform Animal a(i); its constructor gets called and member[val]=-1 but immediately after its iteration the destructor gets called which makes the value back to val. member[index]=index.
How can we delay the call to destructor in this case?
I want the member[5]={-1,-1,-1,-,1,-1} after the for loop ends
and member[5]={0,1,2,3,4} restored to original value only when main() exists.
While it's an ugly hack, how about using a vector that gets destructed after the code you're interested in?
Perhaps something like:
{
std::vector<Animal> animals;
for(int i = 0; i < 5; ++i){
std::cout << member[i] << ' ';
}
std::cout << '\n';
for(int i = 0; i < 5; ++i){
animals.emplace_back(i);
}
for(int i = 0; i < 5; ++i){
std::cout << member[i] << ' ';
}
std::cout << '\n';
// Here the vector object life-time ends
// All Animal object will be destructed
}
As noted, this solution will use the last value of index when the Animal object are being destructed, and since it's never used by the above code it will stay at its (implicitly) initialized value of 0.
You need to store the "index" passed to the constructor in an actual member variable, and use it in the destructor:
class Animal
{
public:
Animal(int index)
: my_index{ index }
{
}
~Animal()
{
member[my_index] = my_index;
}
private:
int my_index;
};
After this you can remove the global index variable, as it's no longer used or needed.

C++: confusion about accessing class data members while multithreading

I have the following minimal working example in which I create a number of markov_chain objects in a vector chains and an equal number of thread objects in a vector workers, each of which executes a markov_chain class member function sample on each of the corresponding markov_chain objects. This function takes some integer (99 in the below example) and assigns it to the acceptance public data member of the markov_chain object. I then print the value of acceptance for each object in the vector.
#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
class markov_chain
{
public:
unsigned int length{0}, acceptance{0};
markov_chain(unsigned int l) {length=l;}
~markov_chain() {}
void sample(int acc);
};
void markov_chain::sample(int acc)
{
acceptance = acc;
std::cout << length << ' ' << acceptance << std::endl;
}
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
for (int i = 0; i <= number_of_threads; i++) {
chains.push_back(markov_chain(number_of_samples));
workers.push_back(std::thread(&markov_chain::sample, chains[i], 99));
}
std::for_each(workers.begin(), workers.end(), [](std::thread &t)
{
t.join();
});
for (int i = 0; i <= number_of_threads; i++) {
std::cout << chains[i].length << ' ' << chains[i].acceptance << std::endl;
}
return 0;
}
Upon executing, the program outputs
1000 99
1000 99
1000 99
1000 99
1000 0
1000 0
1000 0
1000 0
So the program failed to change the value of acceptance for the objects in the vector chains. I don't know why this happens; the function sample successfully assigns the desired value when I use it without creating threads.
There are 2 problems with your code:
when creating each std::thread, you are passing a copy of each object as the this parameter of sample().
Pushing multiple objects into the chains vector the way you are doing may cause the vector to re-allocate its internal array, thus invaliding any object pointers you have already passed to existing threads, since those original objects are now gone after the re-allocation.
You need to fully initialize the chains vector before creating any of the threads. And you need to pass a pointer to each object to each thread.
You can reserve() the array up front to avoid re-allocation while pushing into it, eg:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
chains.reserve(number_of_threads);
for (int i = 0; i < number_of_threads; ++i) {
chains.push_back(markov_chain(number_of_samples));
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}
Demo
However, since all of the objects are being initialized with the same starting value, an easier way is to simply get rid of chains.push_back() altogether and use chains.resize() instead, eg:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
chains.resize(number_of_threads, markov_chain(number_of_samples));
for (int i = 0; i < number_of_threads; ++i) {
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}
Demo
Or, even use the vector constructor itself:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains(number_of_threads, markov_chain(number_of_samples));
std::vector<std::thread> workers;
for (int i = 0; i < number_of_threads; ++i) {
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}
Demo

C++ threads. Why always executes last thread?

Why only last threads executes every time? I'm trying to divide grid into N workers, half of grid always not touchable and other part always proceed by 1 last created thread. Should I use an array instead of vector? Locks also do not help to resolve this problem.
#include <iostream>
#include <unistd.h>
#include <vector>
#include <stdio.h>
#include <cstring>
#include <future>
#include <thread>
#include <pthread.h>
#include <mutex>
using namespace std;
std::mutex m;
int main(int argc, char * argv[]) {
int iterations = atoi(argv[1]), workers = atoi(argv[2]), x = atoi(argv[3]), y = atoi(argv[4]);
vector<vector<int> > grid( x , vector<int> (y, 0));
std::vector<thread> threads(workers);
int start, end, lastworker, nwork;
int chunkSize = y/workers;
for(int t = 0; t < workers; t++){
start = t * chunkSize;
end = start + chunkSize;
nwork = t;
lastworker = workers - 1;
if(lastworker == t){
end = y; nwork = workers - 1;
}
threads[nwork] = thread([&start, &end, &x, &grid, &t, &nwork, &threads] {
cout << " ENTER TO THREAD -> " << threads[nwork].get_id() << endl;
for (int i = start; i < end; ++i)
{
for (int j = 0; j < x; ++j)
{
grid[i][j] = t;
}
}
sleep(2);
});
cout << threads[nwork].get_id() << endl;
}
for(auto& th : threads){
th.join();
}
for (int i = 0; i < y; ++i)
{
for (int j = 0; j < x; ++j)
{
cout << grid[i][j];
}
cout << endl;
}
return(0);
}
[&start, &end, &x, &grid, &t, &nwork, &threads]
This line is the root of the problem. You are capturing all the variables by reference, which is not what you want to do.
As a consequence, each thread uses the same variables, which is also not what you want.
You should only capture grid and threads by reference, the other variables should be captured by value ('copied' into the lambda)
[start, end, x, &grid, t, nwork, &threads]
Also, you are accessing grid wrong everywhere: change grid[i][j] to grid[j][i]
thread([&start, &end, &x, &grid, &t, &nwork, &threads] {
=======
The lambda closure that gets executed by every thread captures a reference to nwork.
Which means that as the for loop iterates and starts every thread, each captured thread will always reference the current value of nwork, at the time it does.
As such, the outer loop probably quickly finishes creating each thread object before all the threads actually initialize and actually enter the lambda closure, and each closure sees the same value of nwork, because it is captured by reference, which is the last thread id.
You need to capture nwork by value instead of by reference.
You're passing all the thread parameters are references to the thread lambda. However, when the loop continues in the main thread, the thread parameter variables change, which changes their values in the threads as well, messing up all the previously-created threads.

print 3 4 5 in sequence for 50 times using semaphore synchronization using three threads in C Linux

My programming is going in dead lock.I am trying to print three numbers 3 4 5 sequentially for 50 times using three threads using semaphore synchronization.
Please help me.
Below is the code
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t sem1;
sem_t sem2;
sem_t sem3;
void * fun1(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem1);
sem_wait(&sem3);
cout<<"3"
sem_post(&sem2);
sem_post(&sem3);
}
}
void * fun2(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem2);
sem_wait(&sem3);
cout<<"4";
sem_post(&sem3);
sem_post(&sem1);
}
}
void * fun3 (void *)
{
for(int i = 0; i< 50; i++)
{
sem_wait(&sem2);
sem_wait(&sem3);
cout<<"5";
sem_post(&sem1);
sem_post(&sem2);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_t t3;
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,1);
pthread_create(&t1,NULL,&fun1,NULL);
pthread_create(&t2,NULL,&fun2,NULL);
pthread_create(&t3,NULL,&fun3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 1;
}
Please help me to understand and solve this deadlock.Provide suggestions also i can do this for example 3 4 5 6 using 4 etc threads
Please help me to understand and solve this deadlock.
There is indeed a deadlock in your code. Consider at the beginning, thread 1 first gets 2 semaphores and call cout << "3". After posting sem2 and sem3, it is possible that thread 3 immediately gets these 2 sem, then call cout << "5". However, after thread 3 posting sem1 and sem2, no one can reach a cout << statement, because sem3's value is 0 and everyone needs to pass a wait of sem3.
If you are wondering why there is totally no output, it's because the buffer inside iostream. For console output, "\n" will flush buffer, so if you replace "3" by "3\n", you can see the output.
Provide suggestions also i can do this for example 3 4 5 6 using 4 etc threads
In the following code, you should see the symmetry, which can be easily generalized to any number of thread. And you should always call sem_destroy after using semaphore, otherwise you might get system level resource leak.
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t sem1;
sem_t sem2;
sem_t sem3;
void * fun1(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem1);
cout<<"3\n";
sem_post(&sem2);
}
}
void * fun2(void *)
{
for(int i = 0; i < 50 ; i++)
{
sem_wait(&sem2);
cout<<"4\n";
sem_post(&sem3);
}
}
void * fun3 (void *)
{
for(int i = 0; i< 50; i++)
{
sem_wait(&sem3);
cout<<"5\n";
sem_post(&sem1);
}
}
int main()
{
pthread_t t1;
pthread_t t2;
pthread_t t3;
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,0);
pthread_create(&t1,NULL,&fun1,NULL);
pthread_create(&t2,NULL,&fun2,NULL);
pthread_create(&t3,NULL,&fun3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 1;
}

How to create a certain number of threads based on a value a variable contains?

I have a integer variable, that contains the number of threads to execute. Lets call it myThreadVar. I want to execute myThreadVar threads, and cannot think of any way to do it, without a ton of if statements. Is there any way I can create myThreadVar threads, no matter what myThreadVar is?
I was thinking:
for (int i = 0; i < myThreadVar; ++i) { std::thread t_i(myFunc); }, but that obviously won't work.
Thanks in advance!
Make an array or vector of threads, put the threads in, and then if you want to wait for them to finish have a second loop go over your collection and join them all:
std::vector<std::thread> myThreads;
myThreads.reserve(myThreadVar);
for (int i = 0; i < myThreadVar; ++i)
{
myThreads.push_back(std::thread(myFunc));
}
While other answers use vector::push_back(), I prefer vector::emplace_back(). Possibly more efficient. Also use vector::reserve(). See it live here.
#include <thread>
#include <vector>
void func() {}
int main() {
int num = 3;
std::vector<std::thread> vec;
vec.reserve(num);
for (auto i = 0; i < num; ++i) {
vec.emplace_back(func);
}
for (auto& t : vec) t.join();
}
So, obvious the best solution is not to wait previous thread to done. You need to run all of them in parallel.
In this case you can use vector class to store all of instances and after that make join to all of them.
Take a look at my example.
#include <thread>
#include <vector>
void myFunc() {
/* Some code */
}
int main()
{
int myThreadVar = 50;
std::vector <thread> threadsToJoin;
threadsToJoin.resize(myThreadVar);
for (int i = 0; i < myThreadVar; ++i) {
threadsToJoin[i] = std::thread(myFunc);
}
for (int i = 0; i < threadsToJoin.size(); i++) {
threadsToJoin[i].join();
}
}
#include <iostream>
#include <thread>
void myFunc(int n) {
std::cout << "myFunc " << n << std::endl;
}
int main(int argc, char *argv[]) {
int myThreadVar = 5;
for (int i = 0; i < myThreadVar; ++i) {
std::cout << "Launching " << i << std::endl;
std::thread t_i(myFunc,i);
t_i.detach();
}
}
g++ -std=c++11 -o 35106568 35106568.cpp
./35106568
Launching 0
myFunc 0
Launching 1
myFunc 1
Launching 2
myFunc 2
Launching 3
myFunc 3
Launching 4
myFunc 4
You need to store the thread so you can send it to join.
std::thread t[myThreadVar];
for (int i = 0; i < myThreadVar; ++i) { t[i] = std::thread(myFunc); }//Start all threads
for (int i = 0; i < myThreadVar; ++i) {t[i].join;}//Wait for all threads to finish
I think this is valid syntax, but I'm more used to c so I am unsure if I initialized the array correctly.