我使用的是 Ubuntu 12,当我在终端上编译代码时,我使用: $ g++ -o ./myProgram ./main.cpp,然后 $ ./myProgram 我没有收到任何错误或警告,但它不会打印主函数之外的任何内容。

由于某种原因,主函数中的 pthread_creat 命令似乎不起作用。

这是我的程序代码:

#include <stdlib.h> 
#include <stdio.h> 
#include <iostream> 
#include <unistd.h> 
#include <time.h> 
#include <pthread.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
 
using namespace std; 
 
pthread_mutex_t jobMutex; 
key_t key = 5678; 
#define SHMSZ 27 
 
int shmid; 
 
class Job { 
public: 
int speed, pleasant, easy; 
 
//initialization, constructor, destructor 
 
Job() { 
} 
 
Job(int new_s, int new_p, int new_e) { 
    speed = new_s; 
    pleasant = new_p; 
    easy = new_e; 
} 
 
~Job() { 
} 
}; 
 
struct sh_data { 
Job j_list[10]; //array of jobs on bulletin board 
int clock; 
int kid_count; 
} *shared, *update; 
 
class Child { 
private: 
int pid; 
int j_pref; 
Job* j_list; 
int clock; 
int score; 
 
public: 
 
Child() { 
} //constructor 
 
void read_mem() { 
    sh_data* data; 
 
    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { 
        cerr << "\tshmget\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    pthread_mutex_lock(&jobMutex); 
 
    if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) { 
        cerr << "\tshmat\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    j_list = data->j_list; 
    clock = data->clock; 
    pthread_mutex_unlock(&jobMutex); 
} 
 
void write_mem(int index) { 
    sh_data* data; 
 
    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { 
        cerr << "\tshmget\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    pthread_mutex_lock(&jobMutex); 
 
    if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) { 
        cerr << "\tshmat\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    data->j_list[index].speed = 0; 
    pthread_mutex_unlock(&jobMutex); 
} 
 
//all preference functions 
 
void pref_quick() { 
    cout << "Child prefers a quick job \n"; 
    read_mem(); 
 
    while (clock < 20) { 
        pthread_mutex_lock(&jobMutex); 
        read_mem(); 
 
        int cur_job; 
        int speed = j_list[0].speed; 
 
        for (int i = 0; i < 10; i++) { 
            if (j_list[i].speed < speed && j_list[i].speed > 0) { 
                cur_job = i; 
                speed = j_list[i].speed; 
            } 
        } 
 
        cout << "Child " << pid << " selected job " << cur_job << " with speed " << speed << "\n"; 
 
        //calculate total score so far 
        score += j_list[cur_job].speed + j_list[cur_job].pleasant + j_list[cur_job].easy; 
 
        write_mem(cur_job); 
        pthread_mutex_unlock(&jobMutex); 
        sleep(j_list[cur_job].speed); 
    } 
} 
 
void pref_profit() { 
    cout << "Child prefers a job with highest profit \n";\ 
    read_mem(); 
 
    while (clock < 20) { 
        pthread_mutex_lock(&jobMutex); 
        read_mem(); 
 
        int cur_job; 
        int profit = 0; 
 
        for (int i = 0; i < 10; i++) { 
            if (j_list[i].speed + j_list[i].pleasant + j_list[i].easy > profit) { 
                cur_job = i; 
                profit = j_list[i].speed + j_list[i].pleasant + j_list[i].easy; 
            } 
        } 
 
        cout << "Child " << pid << " selected job " << cur_job << " with profit " << profit << "\n"; 
 
        //calculate total score so far 
        score += profit; 
 
        write_mem(cur_job); 
        pthread_mutex_unlock(&jobMutex); 
        sleep(j_list[cur_job].speed); 
    } 
} 
 
void pref_simple() { 
    cout << "Child prefers a simple job \n"; 
    read_mem(); 
 
    while (clock < 20) { 
        pthread_mutex_lock(&jobMutex); 
        read_mem(); 
 
        int cur_job; 
        int ease = j_list[0].easy; 
 
        for (int i = 0; i < 10; i++) { 
            if (j_list[i].easy < ease) { 
                cur_job = i; 
                ease = j_list[i].easy; 
            } 
        } 
 
        cout << "Child " << pid << " selected job " << cur_job << " with ease " << ease << "\n"; 
 
        //calculate total score so far 
        score += j_list[cur_job].speed + j_list[cur_job].pleasant + j_list[cur_job].easy; 
 
        write_mem(cur_job); 
        pthread_mutex_unlock(&jobMutex); 
        sleep(j_list[cur_job].speed); 
    } 
} 
 
void pref_clean() { 
    cout << "Child prefers a clean job \n"; 
    read_mem(); 
 
    while (clock < 20) { 
        pthread_mutex_lock(&jobMutex); 
        read_mem(); 
 
        int cur_job; 
        int clean = j_list[0].pleasant; 
 
        for (int i = 0; i < 10; i++) { 
            if (j_list[i].pleasant < clean) { 
                cur_job = i; 
                clean = j_list[i].pleasant; 
            } 
        } 
 
        cout << "Child " << pid << " selected job " << cur_job << " with cleanliness " << clean << "\n"; 
 
        //calculate total score so far 
        score += j_list[cur_job].speed + j_list[cur_job].pleasant + j_list[cur_job].easy; 
 
        write_mem(cur_job); 
        pthread_mutex_unlock(&jobMutex); 
        sleep(j_list[cur_job].speed); 
    } 
} 
 
void* worker() { 
    sh_data* data; 
 
    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { 
        cerr << "\tshmget\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    pthread_mutex_lock(&jobMutex); 
 
    if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) { 
        cerr << "\tshmat\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    j_list = data->j_list; 
    pid = data->kid_count; 
    j_pref = rand() % 4; 
    data->kid_count++; 
    pthread_mutex_unlock(&jobMutex); 
 
    cout << "Job Preference for Child " << pid << " is: " << j_pref << "\n"; 
 
    //select a job preference 
    switch (j_pref) { 
        case 0: //fastest job 
            cout << "Selecting quickest job\n"; 
            pref_quick(); 
            break; 
        case 1: //cleanest job 
            cout << "Selecting the most pleasant job\n"; 
            pref_clean(); 
            break; 
        case 2: //simplest job 
            cout << "Selecting the most simple job\n"; 
            pref_simple(); 
            break; 
        case 3: //most profitable job 
            cout << "Selecting the most profitable job\n"; 
            pref_profit(); 
            break; 
        default: //quickest job by default 
            cout << "Selecting quickest job\n"; 
            pref_quick(); 
            break; 
    } 
} 
 
~Child() { //destructor 
} 
 
//static helper function to get rid of hidden "this" parameter from pthread_create 
 
static void *Child_helper(void *context) { 
    cout << "\tChild helper function called\n"; 
    return ((Child *) context)->worker(); 
} 
}; 
 
class Mom { 
private: 
Job j_list[10]; //unending list of 10 jobs 
int clock; 
pthread_t child_id[4]; //thread ids for each child 
 
public: 
//create job with random speed, pleasant, easy values 
 
Job newJob() { 
    int rand_val[3]; 
 
    for (int i = 0; i < 3; i++) { 
        rand_val[i] = rand() % 5 + 1; 
    } 
 
    return Job(rand_val[0], rand_val[1], rand_val[2]); 
} 
 
void read_mem() { 
    sh_data* data; 
 
    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { 
        cerr << "\tshmget\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    pthread_mutex_lock(&jobMutex); 
 
    if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) { 
        cerr << "\tshmat\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    for (int i = 0; i < 10; i++) { 
        j_list[i] = data->j_list[i]; 
    } 
 
    clock = data->clock; 
    pthread_mutex_unlock(&jobMutex); 
} 
 
void write_mem(Job new_job, int index, int clock) { 
    sh_data* data; 
 
    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { 
        cerr << "\tshmget\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    pthread_mutex_lock(&jobMutex); 
 
    if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) { 
        cerr << "\tshmat\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    data->j_list[index] = new_job; 
    data->clock = clock; 
    pthread_mutex_unlock(&jobMutex); 
} 
 
void write_mem(int clock) { 
    sh_data* data; 
 
    if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { 
        cerr << "\tshmget\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    pthread_mutex_lock(&jobMutex); 
 
    if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) { 
        cerr << "\tshmat\n"; 
        exit(EXIT_FAILURE); 
    } 
 
    data->clock = clock; 
    pthread_mutex_unlock(&jobMutex); 
} 
 
//chores() creates shared memory, checks checks and update shared memory, and creates children 
 
void* chores() { 
    cout << "\tChores function called\n"; 
 
    shmid = shmget(IPC_PRIVATE, 1, IPC_CREAT); 
    cout << "\tValue of shmid: " << shmid << "\n"; 
 
    if (shmid == -1) { 
        shmid = shmget(key, sizeof (sh_data), IPC_CREAT); 
 
        if (-1 == shmid) { 
            cout << "\tCould not get shmid\n"; 
        } else { 
            pthread_mutex_lock(&jobMutex); 
 
            //system chooses the address 
            shared = (sh_data *) shmat(shmid, 0, 0); 
            update = shared; 
 
            pthread_mutex_unlock(&jobMutex); 
        } 
    } else { 
        pthread_mutex_lock(&jobMutex); 
 
        cout << "Mom created job list!\n"; 
 
        //system chooses the address 
        shared = (sh_data *) shmat(shmid, (void*) 0, 0); 
        update = shared; 
        update->kid_count = 0; 
 
        pthread_mutex_unlock(&jobMutex); 
    } 
 
    sh_data* data; 
 
    Child * child[4]; 
 
    for (int i = 0; i < 4; i++) { 
        cout << "~~Thread created for Child " << i + 1 << "\n"; 
        child[i] = new Child(); 
 
        //calls worker function from Child class 
        pthread_create(&child_id[i], NULL, &Child::Child_helper, child[i]); 
    } 
 
    while (clock < 20) { 
        cout << "\tMom will sleep for 2 units\n"; 
        sleep(2); 
        pthread_mutex_lock(&jobMutex); 
        read_mem(); 
 
        for (int i = 0; i < 10; i++) { 
            if (j_list[i].speed == 0) { 
                cout << "Mommy added a new job to the bulletin board!!\n"; 
                j_list[i] = newJob(); 
                write_mem(j_list[i], i, clock); 
            } 
        } 
 
        clock += 2; 
        write_mem(clock); 
        pthread_mutex_unlock(&jobMutex); 
        cout << "Mom says time is now: " << clock << "\n"; 
    } 
 
    payup(); 
} 
 
void payup() { 
    int max, winner; 
 
    max = 0; 
    for (int i = 0; i < 4; i++) { 
        //wait for all children to finish tasks 
        int* status = 0; 
        pthread_join(child_id[i], (void**) status); 
        cout << "Child " << i << " completes tasks that earned him/her " << *status << " points!\n"; 
        if (max < *status) { 
            max = *status; 
            winner = i; 
        } 
    } 
 
    cout << "The winner is child " << winner << ", with " << max << " points!\n"; 
} 
 
Job* get_jlist() { 
    return j_list; 
} 
 
int get_time() { 
    return clock; 
} 
 
//static helper function to get rid of hidden "this" parameter from pthread_create 
 
static void *Mom_helper(void *context) { 
    cout << "\tHelper function called\n"; 
    return ((Mom *) context)->chores(); 
} 
 
//initialization, constructor, destructor 
 
Mom() { 
    srand(time(NULL)); 
} 
 
~Mom() { 
} 
}; 
 
int main() { 
cout << "Program 7: Chores using Threads\n\n"; 
 
pthread_t threads; 
pthread_mutex_init(&jobMutex, NULL); 
 
//instantiate mom class and call chores() 
Mom* mommy = new Mom(); 
cout << "~~Made Mom\n"; 
 
//calls chores function from Mom class 
pthread_create(&threads, NULL, &Mom::Mom_helper, mommy); 
cout << "~~Created threads\n"; 
 
pthread_mutex_destroy(&jobMutex); 
cout << "~~Destroyed threads\n"; 
 
return 0; 
} 

我做错了什么吗?我已经仔细查看并将我的代码与其他代码进行比较,它似乎是正确的。但它不起作用。谁能解释一下这种情况?

请您参考如下方法:

有很多代码需要阅读,但您似乎并没有在等待线程。您的主线程调用 pthread_create 并(可能)在新线程有机会运行之前退出进程。

您可能需要调用pthread_joinpthread_mutex_destroy 之前的某处。

pthread_create(&threads, ...); 
pthread_join(threads, zahir); 


评论关闭
IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!