我正在使用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;
}
我做错了什么,我一直在寻找并将我的代码与其他人进行比较,这似乎是正确的。但它没有用。任何人都可以对这种情况有所了解吗?
答案 0 :(得分:5)
这是要阅读的大量代码,但您似乎并没有等待该线程。你的主线程调用pthread_create
并且(可能)在新线程有机会运行之前退出进程。
您可能希望在pthread_mutex_destroy
之前的某个地方拨打pthread_join
。
pthread_create(&threads, ...);
pthread_join(threads, zahir);