【发布时间】:2014-03-19 04:00:20
【问题描述】:
我目前正在学习如何使用 Pthreads 和 Semaphores,并且我一直在研究生产者/消费者问题的实现,但程序只是挂起。我知道它会到达消费者代码,运行一次比较,然后在默认初始化值比较 p1_string 和 p2_string 后挂起,我真的不明白我到底做错了什么。
基本上,每个生产者线程都应该获取一个已排序行的文件并将一行读入内存。然后主线程应该比较这两个字符串,并按排序顺序将它们写入输出。
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t p1_empty,p2_empty,p1_full,p2_full;
string p1_string="atest", p2_string="btest";
typedef struct {
char* filename;
string buffer;
sem_t empty;
sem_t full;
} pthread_param;
void* producer(void* arg) {
pthread_param* ptp = (pthread_param*)arg;
ifstream input(ptp->filename);
if (not input) {
cerr << "Can't open file \"" << ptp->filename << "\".\n";
exit(EXIT_FAILURE);
}
while(getline(input,ptp->buffer)) {
sem_post(&ptp->full);
sem_wait(&ptp->empty);
}
ptp->buffer = "\x7f";
}
int main(int argc, char* argv[]) {
if (argc != 3) {
cerr << "Syntax: " << argv[0] << " filename filename\n";
exit(EXIT_FAILURE);
}
//init threads, variables and semaphores
sem_init(&p1_empty,0,0);
sem_init(&p2_empty,0,0);
sem_init(&p1_full,0,0);
sem_init(&p2_full,0,0);
pthread_t p1_thread, p2_thread;
pthread_param pt1_param;
pthread_param pt2_param;
pt1_param.filename = argv[1];
pt2_param.filename = argv[2];
pt1_param.buffer = p1_string;
pt2_param.buffer = p2_string;
pt1_param.empty = p1_empty;
pt2_param.empty = p2_empty;
pt1_param.full = p1_full;
pt2_param.full = p2_full;
pthread_create(&p1_thread,nullptr,producer,&pt1_param);
pthread_create(&p2_thread,nullptr,producer,&pt2_param);
/* testing to make sure producer reads correctly
pthread_param* ptp = &pt1_param;
ifstream input(ptp->filename);
if (not input) {
cerr << "Can't open file \"" << ptp->filename << "\".\n";
exit(EXIT_FAILURE);
}
while(getline(input,ptp->buffer)) {
cout<<ptp->buffer<<endl;
}
ptp->buffer = "\x7f";
*/
//consumer
while(pt1_param.buffer != "\x7f" && pt2_param.buffer != "\x7f"){
if(pt1_param.buffer <= pt2_param.buffer) {
cout<<pt1_param.buffer<<endl;
sem_post(&p1_empty);
sem_wait(&p1_full);
}
else {
cout << pt2_param.buffer <<endl;
sem_post(&p2_empty);
sem_wait(&p2_full);
}
}
//delete threads/semaphores
pthread_join(p1_thread,nullptr);
pthread_join(p2_thread,nullptr);
sem_destroy(&p1_empty);
sem_destroy(&p2_empty);
sem_destroy(&p2_full);
sem_destroy(&p2_full);
return 0;
}
【问题讨论】:
-
这是什么?
if (not input)?你的意思是if (!input)?这不是 Python ;-) -
另外,看起来您实际上并没有创建任何消费者线程。你想在
main内部完成什么? -
基本上每个生产者都会获取一个已排序行的文件,并且需要读取一行并将其保存为字符串。然后当两个生产者需要比较它们时,选择较小的字符串,将其写入输出,然后提示该线程输入新字符串。