具有多个线程的程序,不打印预期输出
Program with multiple threads, not printing expected output
我使用的是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 << "tshmgetn";
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&jobMutex);
if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) {
cerr << "tshmatn";
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 << "tshmgetn";
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&jobMutex);
if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) {
cerr << "tshmatn";
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 << "tshmgetn";
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&jobMutex);
if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) {
cerr << "tshmatn";
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 jobn";
pref_quick();
break;
case 1: //cleanest job
cout << "Selecting the most pleasant jobn";
pref_clean();
break;
case 2: //simplest job
cout << "Selecting the most simple jobn";
pref_simple();
break;
case 3: //most profitable job
cout << "Selecting the most profitable jobn";
pref_profit();
break;
default: //quickest job by default
cout << "Selecting quickest jobn";
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 calledn";
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 << "tshmgetn";
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&jobMutex);
if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) {
cerr << "tshmatn";
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 << "tshmgetn";
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&jobMutex);
if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) {
cerr << "tshmatn";
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 << "tshmgetn";
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&jobMutex);
if ((data = (sh_data *) shmat(shmid, NULL, 0)) == (sh_data *) -1) {
cerr << "tshmatn";
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 calledn";
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 shmidn";
} 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 unitsn";
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 calledn";
return ((Mom *) context)->chores();
}
//initialization, constructor, destructor
Mom() {
srand(time(NULL));
}
~Mom() {
}
};
int main() {
cout << "Program 7: Chores using Threadsnn";
pthread_t threads;
pthread_mutex_init(&jobMutex, NULL);
//instantiate mom class and call chores()
Mom* mommy = new Mom();
cout << "~~Made Momn";
//calls chores function from Mom class
pthread_create(&threads, NULL, &Mom::Mom_helper, mommy);
cout << "~~Created threadsn";
pthread_mutex_destroy(&jobMutex);
cout << "~~Destroyed threadsn";
return 0;
}
我做错了什么吗?我一直在到处寻找,并将我的代码与其他代码进行比较,结果似乎是正确的。但它不起作用。有人能解释一下这种情况吗?
这有很多代码要读,但您似乎没有在等待线程。您的主线程调用pthread_create
,并且(很可能)在新线程有机会运行之前退出进程。
你可能想打电话给pthread_join
,在pthread_mutex_destroy
之前的某个地方。
pthread_create(&threads, ...);
pthread_join(threads, zahir);
相关文章:
- 数组类 阵列的打印输出
- 打印输出在主,而不是在函数中
- 执行ls命令并打印输出
- 在代码仍在 C++ QT 中运行时显示打印输出
- 函数打印输出C 的错误
- 如果关闭娱乐后()所有内存都会被交易,则如何打印输出
- 如何水平排列程序的打印输出循环而不重复
- 程序被卡住了,不打印输出
- 使用递归打印输出
- 指针类函数不打印输出
- 没有得到 ASCII 编号 = 7 的字符串打印输出
- 以未格式化的输出 c++ 打印输出
- 将值输入到结构数组 + 打印输出
- 程序运行,但程序中的第二个功能不打印?输出中没有错误
- 抑制Python打印输出
- 输出正确,但每次打印输出后程序崩溃
- 无限循环heisenbug:如果我添加打印输出,它就会退出
- 为类打印输出(打印调试信息)的最佳实践是什么?
- 正在检查CppUnit中的打印输出
- 如何在C++中解决此打印输出