简体   繁体   中英

C++ class member variable initialization with thread

I am implementing a threading example with classes and passing argument to thread as a structure. I initialize class-members for each of the four threads but somehow one class-member is not getting initialized and it is getting initiated to garbage value. I tried reducing number of threads to 3, however the same class-member is getting initialed to garbage value.

In the below Dining Philosopher example attempt, Philosopher(thread)1 fork2 is getting initialized to garbage value.

#include <iostream>
#include <stdio.h>
#include "PhilOne.h"
#include <pthread.h>

using namespace std;

#define NUM_PHIL 4

struct phil_data {
    int thread_id;
    int fork1;
    int fork2;
};

void *StartPhil(void *threadarg){
    struct phil_data *my_data;
    my_data = (struct phil_data *) threadarg;

    int tid = my_data->thread_id;
    int my_fork1 = my_data->fork1;
    int my_fork2 = my_data->fork2;

    cout << "Hello World! I am Philosopher number, " << tid << endl;
    cout << "My fork1 is:" << my_fork1 << endl;
    cout << "My fork2 is:" << my_fork2 << endl;

    PhilOne phil[tid];
    phil[tid].waitForForks();
    phil[tid].eat();
    phil[tid].releaseForks();
    phil[tid].think();
    std::cout<<std::endl;

    pthread_exit(NULL);
}

int main(){
    pthread_t threads[NUM_PHIL];
    struct phil_data td[NUM_PHIL];
    int rc;
    int i;

    for (i=0;i<NUM_PHIL;i++){
        //pthread_mutex_lock(&lock);
        cout << "main(): creating Philosopher," << i << endl;
        td[i].thread_id = i;

        switch (i){
            case 0:
                {
                    td[i].fork1=0;
                    td[i].fork2=1;
                    break;
                }
            case 1:
                {
                    td[i].fork1=1;
                    td[i].fork2=5;
                    break;
                }
            case 2:
                {
                    td[i].fork1=2;
                    td[i].fork2=3;
                    break;
                }
            case 3:
                {
                    td[i].fork1=3;
                    td[i].fork2=0;
                    break;
                }
            default:
                break;
        }

        rc = pthread_create(&threads[i],NULL,StartPhil,(void *)&td[i]);
        if (rc){
            cout << "Error:unable to create thread," << rc << endl;
            exit(-1);
        }
    }
    pthread_exit(NULL);
}

Below is PhilOne.cpp


#include "PhilOne.h"
#include <iostream>

using namespace std;

PhilOne::PhilOne(){
    //ctor

}

PhilOne::~PhilOne(){
    //dtor
}

int PhilOne::eat(){
    cout << "Eating ...." << endl;
    sleep(2);
    return 0;
}

int PhilOne::releaseForks()
{
    std::cout << "Released forks ...." <<std::endl;
    return 0;
}

int PhilOne::think()
{
    std::cout << "Thinking...." <<std::endl;
    sleep(1);
    return 0;
}

int PhilOne::waitForForks()
{
    std::cout << "Waiting for forks...." <<std::endl;
    sleep(3);
    return 0;
}

产量

I am not able to reproduce your result but there appears to be some Undefined Behavior in the program.

PhilOne phil[tid];
phil[tid].waitForForks();

What is the purpose of declaring an array of PhilOne objects? The second line will access the object that is one -after- the array. I think you just need

PhilOne phil;
phil.waitForForks();

Try fixing that up and it may correct your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM