Unique value within POSIX thread - c++

I am trying to pass into each thread a struct and have each thread print out the value within the struct and show that it is unique per thread.
My problem is that each thread prints out the same value even though i change the value right before passing it in.
const int NUM_THREADS = 2;
struct number
{
int uniqueNumber;
};
void* showUniqueNumber(void* numberStruct);
int main()
{
pthread_t threadID[NUM_THREADS];
number* numberPtr = new number();
for(int i=0; i < NUM_THREADS; i++)
{
numberPtr->uniqueNumber = i;
pthread_create(&threadID[i], NULL, showUniqueNumber, (void*)numberPtr);
}
for(int i=0; i < 5; i++)
{
pthread_join(threadID[i], NULL);
}
return 0;
}
void* showUniqueNumber(void* numberStruct)
{
number* threadPtrN = (number*)numberStruct;
cout << threadPtrN->uniqueNumber << endl;
return (void*)0;
}

It's because it's the same object. You can do this:
pthread_t threadID[NUM_THREADS];
number numbers[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++)
{
numbers[i].uniqueNumber = i;
pthread_create(&threadID[i], NULL, showUniqueNumber, numbers + i);
}

Related

process exited due to signal 6/11 c++

I didn't have any problems with compiling my program, but I have a big one when I try to use a bot to check output data. It says: "process exited due to signal 6" or "process exited due to signal 11". I thought it was a matter of dynamic arrays (i have two in this program) but both are deleted at the end.
I would be very grateful for any tip!
#include <iostream>
using namespace std;
void input_data (int p_n, int **p_arr);
void output_data (int p_n, int **p_arr);
void check_salary(int p_n, int **p_arr);
int main()
{
int n;
cin >> n;
int** arr = new int*[n];
for(int i = 0; i < n; ++i){
arr[i] = new int[2];}
input_data(n, arr);
check_salary(n, arr);
output_data(n, arr);
for(int i=0; i<n; i++) {
delete [] arr[i];
}
delete[] arr;
return 0;
}
void check_salary(int p_n, int **p_arr)
{
bool fit, flag, exist;
int *used = new int(p_n);
int boss, salary, i_temp, i_salarless, min_sal ,i_used = 0,boss_salary, id;
for (int i=0; i<p_n; i++)
{
if(p_arr[i][1] != 0)
{
used[i_used]=p_arr[i][1];
i_used++;
}
}
do{
flag = false;
exist=false;
for (int i=0; i<p_n; i++)
{
i_salarless = 0;
id = i+1;
boss = p_arr[i][0];
salary=p_arr[i][1];
boss_salary = p_arr[boss-1][1];
if(salary==0)
{
if(boss==id){
p_arr[i][1] = p_n;
flag = true;
}else if(boss_salary>0){
for (int j=0; j<p_n; j++)
{
if (p_arr[j][0]==boss && p_arr[j][1] == 0){i_salarless++;}
}
if (i_salarless == 1){
do{
--boss_salary;
exist = false;
for (int i=0; i< i_used; i++){
{
if(boss_salary == used[i]){exist = true;}
}
}
}while(exist);
p_arr[i][1]= boss_salary;
used[i_used]= p_arr[i][1];
i_used++;
flag = true;
}
}
}else{}
}
} while(flag);
delete []used;
}
void output_data (int p_n, int **p_arr)
{
for (int i=0; i<p_n; i++)
{
cout<< p_arr[i][1] << "\n";
}
}
void input_data (int p_n, int **p_arr)
{
for (int i=0; i<p_n; i++)
{
for (int j=0; j<2; j++)
{
cin>> p_arr[i][j];
}
}
}
I think the main issue is that you are doing int *used = new int(p_n);, this will create a pointer to an integer that has initial value equal to p_n. But, the problem comes here: used[i_used]=p_arr[i][1]; -- this may lead to a segmentation fault, as you may end up using memory outside the valid bounds.
I'm not sure about the algorithm, but based on the code, I think you should use this instead:
used = new int[p_n]; // assuming p_n > 0

Unexpected number output

I'm trying to create a program that solves the problem of dining philosophers using posix threads. However, I got stuck at the very beginning, since the output of std :: cout << id + 1 << "PHILOSOPHER: thinking" << std :: endl; ++ i; is incorrect and id takes too large values. Please point out my mistake.
pthread_mutex_t mutexSpoon[PHILOSOPHERS];
pthread_t createThread(int number){
pthread_t id;
int rc = pthread_create(&id, NULL, philFunc, &number);
if(rc){
abort();
}
return id;
}
void *philFunc(void *arg){
srand(time(0));
int id = *(int*)arg;
int leftSpoon = (id>0) ? id-1 : PHILOSOPHERS;
int rightSpoon = id;
int temp;
int i = 0;
while(i < 10){
usleep((200 - 50) * ( (double)rand() / RAND_MAX ) + 50);
std::cout << id+1 << " PHILOSOPHER: thinking" << std::endl; ++i;
}
return nullptr;
}
main.cpp
using namespace std;
extern pthread_mutex_t mutexSpoon[PHILOSOPHERS];
int main(){
setlocale(LC_ALL, "rus");
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_mutex_init(&mutexSpoon[i], NULL);
vector<pthread_t> vecID(PHILOSOPHERS);
for(int i = 0; i < PHILOSOPHERS; ++i)
vecID[i] = createThread(i);
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_join(vecID[i], NULL);
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_mutex_destroy(&mutexSpoon[i]);
return 0;
}
thread function uses an address for argument, which you pass as an address to a local variable of function createThread - number. The life span of argument should be not shorter than thread, so exactly same as the mutex. Using your snippets as base, I created an example which works around the issue:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <pthread.h>
#include <unistd.h>
void *philFunc(void *arg);
#define PHILOSOPHERS 10
struct Philosopher {
pthread_mutex_t mutexSpoon;
pthread_t id;
int no;
};
Philosopher philosophers[PHILOSOPHERS] = {};
pthread_t createThread(int& number){
pthread_t id;
int rc = pthread_create(&id, NULL, philFunc, &number);
if(rc){
abort();
}
return id;
}
void *philFunc(void *arg){
srand(time(0));
int id = *(int*)arg;
int leftSpoon = (id>0) ? id-1 : PHILOSOPHERS;
int rightSpoon = id;
int temp;
int i = 0;
while(i < 10){
usleep((200 - 50) * ( (double)rand() / RAND_MAX ) + 50);
std::cout << id+1 << " PHILOSOPHER: thinking" << std::endl; ++i;
}
return nullptr;
}
extern pthread_mutex_t mutexSpoon[PHILOSOPHERS];
int main(){
setlocale(LC_ALL, "rus");
for(int i = 0; i < PHILOSOPHERS; ++i) {
pthread_mutex_init(&philosophers[i].mutexSpoon, NULL);
philosophers[i].no = i;
philosophers[i].id = createThread(philosophers[i].no);
}
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_join(philosophers[i].id, NULL);
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_mutex_destroy(&philosophers[i].mutexSpoon);
return 0;
}
As you see, there is now own structure Philosopher for each thread, storing its data as it should be. While philosophers here is an array, it can be any other container as long as its elements live long enough and aren't changing their addresses (requirement for some implementations of the pthread mutex).
Note that createThread(int& number) now takes its argument by reference, so the expression &number would get address of the actual object's location, not of local variable.
This code can be simpler, if using C++ thread support and std::future.

Boost returning values from multithread vector

I am trying to develop a code which generates N threads into a loop. Each thread generates 40 random numbers and pick from them the highest. Afterwards, I have to choose the highest number from all. However, when I return the highest value of each thread (b) it is empty, this is the code I am using:
class rdm_thr
{
public:
rdm_thr()
{
}
void rdmgen()
{
default_random_engine generator;
double rdm;
b=0;
normal_distribution<double> normal(0, 1);
for(int i=0; i<40; i++)
{
rdm = normal(generator);
if(rdm>b)
b = rdm;
}
}
};
void main()
{
vector<boost::thread *> z;
vector<rdm_thr> o;
boost::function<void()> th_func;
for (int i = 0; i < 2; i++)
o.push_back(rdm_thr());
for (int i = 0; i < 2; i++)
{
th_func = boost::bind(&rdm_thr::rdmgen, &o[i]);
boost::thread thr(th_func);
z.push_back(&thr);
}
for (int i = 0; i < 2; i++)
{
z[i]->join();
}
}
Is there another way to do it?
You could change your class logic as such:
class rdm_thr
{
public:
rdm_thr() {}
void rdmgen()
{
...
}
void join() { t.join(); }
void start()
{
t = boost::thread(boost::bind(&rdm_thr::rdmgen, this));
}
private:
boost::thread t;
// could also be pointer type and 'new/delete' would have to be used in that event
};
#define TSZ 2
void main()
{
std::vector<rdm_thr*> o;
int i = 0;
for (; i < TSZ; i++) {
o.push_back(new rdm_thr());
o.back()->start();
}
for (i = 0; i < TSZ; i++) {
o[i]->join();
delete o[i]; //clean up
}
}
And if you didn't want to change your class logic, you could do the following in your main function:
#define TSZ 2
void main()
{
std::vector<boost::thread *> z;
std::vector<rdm_thr *> o;
int i = 0;
for (; i < TSZ; i++) {
o.push_back(new rdm_thr());
z.push_back(new boost::thread(boost::bind(&rdm_thr::rdmgen, o.back())));
}
for (i = 0; i < TSZ; i++) {
z[i]->join();
delete z[i];
delete o[i];
}
}
I don't have access to a compiler right now so I can't verify 100%, but as your asking more on theory, the above code is to help illustrate alternative ways of achieving similar results.
I hope that can help

measured runtime from c++ "time.h" is double than real

I am running this pthread-c++ program (gauss elimination) on my laptop to measure its runtime.
The program runs about 10 seconds in real but my output shows about 20 seconds. What is wrong with this program?
I used
g++ -pthread main.c
./a.out 32 2048
to run
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <cstdlib>
#include <pthread.h>
#include <iostream>
typedef float Type;
void mat_rand (Type**, int, int);
Type** mat_aloc (int, int);
void mat_free (Type**);
void mat_print (Type**, int, int);
void* eliminate(void*);
unsigned int n, max_threads, active_threads, thread_length;
Type** A;
int current_row;
struct args
{
int start;
int end;
};
typedef struct args argument;
void *print_message_function( void *ptr );
int main(int argc, char *argv[])
{
if (argc < 3)
{
printf ("Error!. Please Enter The Matrix Dimension and No. of Threads!\n");
return 0;
} else
{
n = atoi(argv[2]);
max_threads = atoi(argv[1]);
if (n > 4096)
{
printf ("The maximum allowed size is 4096!\n");
return 0;
}
if (max_threads > 32)
{
printf ("The maximum allowed Threads Count is 32!\n");
return 0;
}
}
A = mat_aloc(n , n+1);
mat_rand (A, n, n+1);
//mat_print (A, n, n+1);
std::clock_t start;
double exe_time;
start = std::clock();
pthread_attr_t attr;
pthread_attr_init(&attr);
argument* thread_args = new argument[max_threads];
pthread_t* thread = new pthread_t[max_threads];
for (int i=0; i<n-1; i++)
{
current_row = i;
if (max_threads >= n-i)
active_threads = n-i-1;
else
active_threads = max_threads;
thread_length = (n-i-1)/active_threads;
for (int j=0; j<active_threads-1; j++)
{
thread_args[j].start = i+1+j*thread_length;
thread_args[j].end = i+1+(j+1)*thread_length;
pthread_create( &thread[j], &attr, eliminate, (void*) &thread_args[j]);
}
thread_args[active_threads-1].start = i+1+(active_threads-1)*thread_length;
thread_args[active_threads-1].end = n-1;
pthread_create(&thread[active_threads-1], &attr, eliminate, (void*) &thread_args[active_threads-1]);
for (int j=0; j<active_threads; j++)
{
pthread_join(thread[j], NULL);
}
}
exe_time = (clock() - start) / (double) CLOCKS_PER_SEC;
printf("Execution time for Matrix of size %i: %f\n", n, exe_time);
//mat_print (A, n, n+1);
return 0;
}
void* eliminate(void* arg)
{
Type k, row_constant;
argument* info = (argument*) arg;
row_constant = A[current_row][current_row];
for (int i=info->start; i<=info->end; i++)
{
k = A[i][current_row] / row_constant;
A[i][current_row] = 0;
for (int j=current_row+1; j<n+1; j++)
{
A[i][j] -= k*A[current_row][j];
}
}
}
// matrix random values
void mat_rand (Type** matrix, int row, int column)
{
for (int i=0; i<row; i++)
for (int j=0; j<column; j++)
{
matrix[i][j] = (float)(1) + ((float)rand()/(float)RAND_MAX)*256;
}
}
// allocates a 2d matrix
Type** mat_aloc (int row, int column)
{
Type* temp = new Type [row*column];
if (temp == NULL)
{
delete [] temp;
return 0;
}
Type** mat = new Type* [row];
if (temp == NULL)
{
delete [] mat;
return 0;
}
for (int i=0; i<row; i++)
{
mat[i] = temp + i*column;
}
return mat;
}
// free memory of matrix
void mat_free (Type** matrix)
{
delete[] (*matrix);
delete[] matrix;
}
// print matrix
void mat_print (Type** matrix, int row, int column)
{
for (int i=0; i<row; i++)
{
for (int j=0; j<column; j++)
{
std::cout<< matrix[i][j] << "\t\t";
}
printf("\n");
}
printf(".................\n");
}
clock reports CPU time used. If you have 2 CPUs and run a thread on each one for 10 seconds, clock will report 20 seconds.

Implementation of Lamport's Bakery Algorithm has seg faults with more than 1 thread

I'm implementing Lamport's Bakery Algorithm using pthreads and a Processor class to act as shared memory. With a single thread it works fine, with 2 threads I get the seg fault after thread 2 runs through all 30 attempts to access the 'bakery':
dl-tls.c: No such file or directory.
With 3 or more threads I get the seg fault after outputting "here" twice from the bakeryAlgo function:
0x0804ae52 in Processor::getNumber (this=0x5b18c483) at Processor.cpp:33
bakery.cpp
struct argStruct {
vector<Processor>* processors;
Processor* processor;
};
int findMax(vector<Processor>* processors) {
int max = -99;
for (int i = 0; i < processors->size(); i++) {
if (processors->at(i).getNumber() > max) {
max = processors->at(i).getNumber();
}
}
return max;
}
void* bakeryAlgo(void* arg) {
struct argStruct* args = static_cast<struct argStruct *>(arg);
cout << "here" << endl;
for (int i = 0; i < 30; i++) {
args->processor->setChoosing(1);
args->processor->setNumber(findMax(args->processors));
args->processor->setChoosing(0);
for (int j = 0; j < args->processors->size(); j++) {
int jChoosing = args->processors->at(j).getChoosing();
int jNumber = args->processors->at(j).getNumber();
int jId = args->processors->at(j).getId();
int pNumber = args->processor->getNumber();
int pId = args->processor->getId();
if (jId != pId) {
while (jChoosing != 0) {}
while (jNumber != 0 && ((jNumber < pNumber) || ((jNumber == pNumber) && (jId < pId)))) { }
}
}
cout << "Processor: " << args->processor->getId() << " executing critical section!" << endl;
args->processor->setNumber(0);
}
}
int main(int argc, char *argv[]) {
// Check that a command line argument was provided
if (2 == argc) {
int numProcessors = atoi(argv[1]);
vector<Processor> processors;
vector<argStruct> argVect;
vector < pthread_t > threads;
for (int i = 0; i < numProcessors; i++) {
Processor p = Processor(i);
processors.push_back(p);
}
for (int i = 0; i < numProcessors; i++) {
pthread_t processorThread;
struct argStruct args;
args.processors = &processors;
args.processor = &processors.at(i);
argVect.push_back(args);
threads.push_back(processorThread);
pthread_create(&threads.at(i), NULL, &bakeryAlgo, &argVect.at(i));
}
for (int i = 0; i < numProcessors; i++) {
pthread_join(threads.at(i), NULL);
}
}
else {
cout << "Usage: bakery num, num is number of threads." << endl;
}
return 0;
}
The code in Processor.cpp / Processor.h is simple, it's just a few getters and setters on the values id, choosing, and number, with a default constructor and a constructor that takes an int id.
Processor::Processor() {
}
Processor::Processor(int idval) {
id = idval;
choosing = 0;
number = 0;
}
Processor::~Processor() {
}
int Processor::getChoosing() {
return choosing;
}
int Processor::getNumber() {
return number;
}
int Processor::getId() {
return id;
}
void Processor::setChoosing(int c) {
choosing = c;
}
void Processor::setNumber(int n) {
number = n;
}
Does anyone have any idea why these seg faults are occuring? The places gdb says they are occuring look like innocent lines of code to me.
Are you using a pointer to a vector defined in main as your data? Stack is not shared among threads, so the other threads accessing this memory would be undefined behavior at best. I expect this is the source of your troubles.
You are taking the address of an element in a vector which is changing:
for (int i = 0; i < numProcessors; i++) {
pthread_t processorThread;
struct argStruct args;
args.processors = &processors;
args.processor = &processors.at(i);
argVect.push_back(args);
threads.push_back(processorThread);
// danger!
pthread_create(&threads.at(i), NULL, &bakeryAlgo, &argVect.at(i));
}
Each time a new thread is pushed onto the threads vector, the vector may be relocated in memory, so the pointer that you passed to pthread_create may be pointing to garbage when the next thread is added.
You want to do this instead:
for (int i = 0; i < numProcessors; i++) {
pthread_t processorThread;
struct argStruct args;
args.processors = &processors;
args.processor = &processors.at(i);
argVect.push_back(args);
threads.push_back(processorThread);
}
for (int i = 0; i < numProcessors; i++) {
pthread_create(&threads.at(i), NULL, &bakeryAlgo, &argVect.at(i));
}
By waiting until all the elements are added to the vector before you create your threads, you are now passing pointers that stay good while the threads are running.