我需要一些算法帮助我写一个多线程程序。它基本上是unix中的cp命令,但有一个读线程和一个写线程。我使用信号量进行线程同步。我有结构化缓冲区和线程数据定义为
struct bufType {
char buf[BUFFER_SIZE];
int numBytes;
};
struct threadData {
int fd;
bufType buf;
};
和bufType的全局数组。我的主要代码是
int main(int argc, const char * argv[])
{
int in, out;
pthread_t Producer, Consumer;
threadData producerData, consumerData;
if (argc != 3)
{
cout << "Error: incorrect number of params" << endl;
exit(0);
}
if ((in = open(argv[1], O_RDONLY, 0666)) == -1)
{
cout << "Error: cannot open input file" << endl;
exit(0);
}
if ((out = open(argv[2], O_WRONLY | O_CREAT, 0666)) == -1)
{
cout << "Cannot create output file" << endl;
exit(0);
}
sem_init(&sem_empty, 0, NUM_BUFFERS);
sem_init(&sem_full, 0, 0);
pthread_create (&Producer, NULL, read_thread, (void *) &producerData);
pthread_create (&Consumer, NULL, write_thread, (void *) &consumerData);
pthread_join(Producer, NULL);
pthread_join(Consumer, NULL);
return 0;
}
并读写线程:
void *read_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
while((thread_data->buf.numBytes = slow_read(thread_data->fd, thread_data->buf.buf, BUFFER_SIZE)) != 0)
{
sem_post(&sem_full);
sem_wait(&sem_empty);
}
pthread_exit(0);
}
void *write_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
sem_wait(&sem_full);
slow_write(thread_data->fd, thread_data->buf.buf, thread_data->buf.numBytes);
sem_post(&sem_empty);
pthread_exit(0);
}
所以我的问题是在main中分配给我的threadData变量,在读写线程中分配我的信号量逻辑。感谢您提供的任何帮助
答案 0 :(得分:0)
您可以使用公共缓冲池,圆形阵列或链接列表。这是一个Windows示例的zip链接,它类似于您所要求的,使用链接列表作为线程间消息传递系统的一部分来缓冲数据。除了创建互斥锁,信号量和写入线程之外,这些函数既小又简单。 mtcopy.zip。
答案 1 :(得分:0)
作为一个不使用文件描述符的windows家伙,我可能错了in和out,但我认为这需要在你的main中完成才能设置threadData结构。
producerData.fd = in;
consumerData.fd = out;
然后为两个结构声明类型为bufType的ONE SINGLE对象。例如,将threadData的定义更改为
struct threadData {
int fd;
bufType* buf;
};
在您的主页中,您可以写
bufType buffer;
producerData.buf = &buffer;
consumerData.buf = &buffer;
然后两个线程将使用公共缓冲区。否则你将写入producerData缓冲区,但consumerData缓冲区将保持为空(这是你的编写器线程正在寻找数据的地方)
然后你需要改变你的信号逻辑。现在你的程序不能接受超过BUFFER_SIZE
的输入,因为你的写线程只会写一次。需要围绕它循环。然后你需要一些机制来通知作者线程不再发送数据。例如,你可以这样做
void *read_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
while((thread_data->buf->numBytes = slow_read(thread_data->fd, thread_data->buf->buf, BUFFER_SIZE)) > 0)
{
sem_post(&sem_full);
sem_wait(&sem_empty);
}
sem_post(&sem_full); // Note that thread_data->buf->numBytes <= 0 now
pthread_exit(0);
}
void *write_thread(void *data)
{
threadData *thread_data;
thread_data = (threadData *) data;
sem_wait(&sem_full);
while (thread_data->buf->numBytes > 0)
{
slow_write(thread_data->fd, thread_data->buf->buf, thread_data->buf->numBytes);
sem_post(&sem_empty);
sem_wait(&sem_full);
}
pthread_exit(0);
}
希望没有更多的错误,没有测试解决方案。但这个概念应该是你所要求的。