Linux C多线程按行读文件的有关问题
Linux C多线程按行读文件的问题
基本意思就是:两个线程度一个大的文本文件,一个生产者,一个消费者。
生产者按行读一行,然后消费者将此行打印输出,如此交替进行。
我的问题是:同步很难实现,已经使用了锁仍然但是仍然会乱,比如某一行重复输出多次,某一行缺失。用sleep函数会非常没效率。
所以,不知各位有没有什么办法解决这个问题?
------解决思路----------------------
LZ 的意思是1个线程读文件,另外的一个线程把读取的内容打印出来
启动AB两个线程
B线程启动后进入wait状态
A线程读取文件 ,把读取的文件内容给变量G
notify B线程,之后进入wait状态
B线程被唤醒,打印变量G,
notify A线程,然后进入wait状态
之后A线程被唤醒,读取文件,如此往复
------解决思路----------------------
1)起一个全局变量,read和print线程都可以看得到;
2)开一对pipe(管道,阻塞模式), read线程写管道,print线程读管道
3)运行中,read线程每读一行数据(数据放在全局里面),就写管道;print线程则循环读管道。读到之后,就去打印全局变量
------解决思路----------------------
编译: gcc test.c -lrt
------解决思路----------------------
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define BUFSIZE 32
int term = 0; // if read_thread terminates, term is set to 1
int fd_s; // the source file
int fd_d; // the destination
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
char buf[BUFSIZE];
void *read_t(void *);
void *write_t(void *);
int main(int argc, char *argv[])
{
pthread_t read_thread;
pthread_t write_thread;
if (argc != 3)
{
printf ("Error: usage %s <file>\n", argv[0]);
exit (0);
}
fd_s = open(argv[1], O_RDONLY);
if (fd_s==-1)
{
perror("open source file");
exit (0);
}
fd_d = open(argv[2], O_WRONLY
------解决思路----------------------
O_CREAT
------解决思路----------------------
O_TRUNC, 0644); // If the file denoted by argv[2] does not exist, the kernel will create it
// If the file exists, it will be truncated to zero length
if (fd_d==-1)
{
perror("open destination file");
exit (0);
}
bzero(buf, BUFSIZE);
pthread_create(&read_thread, NULL, read_t, NULL);
pthread_create(&write_thread, NULL, write_t, NULL);
pthread_join(read_thread, NULL);
pthread_join(write_thread, NULL);
return 0;
}
void *read_t(void *null)
{
int ret;
while (1)
{
pthread_mutex_lock(&mutex);
if (strlen(buf)==0)
{
ret = read(fd_s, buf, BUFSIZE);
if (ret==0)
{
term = 1;
pthread_mutex_unlock(&mutex);
break;
}
if (ret==-1)
{
perror("read");
exit (0);
}
}
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *write_t(void *null)
{
int ret;
while (1)
{
pthread_mutex_lock(&mutex);
if (strlen(buf)!=0)
{
ret = write(fd_d, buf, BUFSIZE);
if (ret==-1)
{
perror("write");
exit (0);
}
bzero(buf, BUFSIZE);
}
pthread_mutex_unlock(&mutex);
if (term)
break;
}
return NULL;
}
基本意思就是:两个线程度一个大的文本文件,一个生产者,一个消费者。
生产者按行读一行,然后消费者将此行打印输出,如此交替进行。
我的问题是:同步很难实现,已经使用了锁仍然但是仍然会乱,比如某一行重复输出多次,某一行缺失。用sleep函数会非常没效率。
所以,不知各位有没有什么办法解决这个问题?
------解决思路----------------------
LZ 的意思是1个线程读文件,另外的一个线程把读取的内容打印出来
启动AB两个线程
B线程启动后进入wait状态
A线程读取文件 ,把读取的文件内容给变量G
notify B线程,之后进入wait状态
B线程被唤醒,打印变量G,
notify A线程,然后进入wait状态
之后A线程被唤醒,读取文件,如此往复
------解决思路----------------------
1)起一个全局变量,read和print线程都可以看得到;
2)开一对pipe(管道,阻塞模式), read线程写管道,print线程读管道
3)运行中,read线程每读一行数据(数据放在全局里面),就写管道;print线程则循环读管道。读到之后,就去打印全局变量
------解决思路----------------------
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
int pipes[2];
void* PrintThread(void*para)
{
int len = 0;
char buf[1024];
(void)para;
while(1)
{
len = read(pipes[0],buf,sizeof(buf));
if(len < 1)
{
perror("read");
break;
}
if(strcmp(buf,"quit"))
{
printf("%s",buf);
continue;
}
close(pipes[0]);
return NULL;
}
}
void* ReadThread(void*para)
{
FILE* fp = (FILE*)para;
int len = 0;
char*p = NULL;
char buf[1024];
while(1)
{
bzero(buf,sizeof(buf));
p = fgets(buf,1024,fp);
if(!p)
{
strcpy(buf,"quit");
write(pipes[1],buf,strlen(buf));
break;
}
write(pipes[1],buf,strlen(buf));
}
close(pipes[1]);
return NULL;
}
int main(int argc,char*argv[])
{
pthread_t pidread,pidprint;
int ret;
FILE* fp = fopen(argv[1],"r");
if(!fp)
{
perror("fopen");
return 1;
}
ret = pipe(pipes);
if(ret != 0)
{
perror("pipe");
fclose(fp);
return 1;
}
ret = pthread_create(&pidprint,NULL,PrintThread,NULL);
ret
------解决思路----------------------
= pthread_create(&pidread,NULL,ReadThread,(void*)fp);
if(ret != 0)
{
perror("pthread_create");
fclose(fp);
close(pipes[0]);
close(pipes[1]);
return 1;
}
pthread_join(pidprint,NULL);
pthread_join(pidread,NULL);
return 0;
}
编译: gcc test.c -lrt
------解决思路----------------------
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define BUFSIZE 32
int term = 0; // if read_thread terminates, term is set to 1
int fd_s; // the source file
int fd_d; // the destination
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
char buf[BUFSIZE];
void *read_t(void *);
void *write_t(void *);
int main(int argc, char *argv[])
{
pthread_t read_thread;
pthread_t write_thread;
if (argc != 3)
{
printf ("Error: usage %s <file>\n", argv[0]);
exit (0);
}
fd_s = open(argv[1], O_RDONLY);
if (fd_s==-1)
{
perror("open source file");
exit (0);
}
fd_d = open(argv[2], O_WRONLY
------解决思路----------------------
O_CREAT
------解决思路----------------------
O_TRUNC, 0644); // If the file denoted by argv[2] does not exist, the kernel will create it
// If the file exists, it will be truncated to zero length
if (fd_d==-1)
{
perror("open destination file");
exit (0);
}
bzero(buf, BUFSIZE);
pthread_create(&read_thread, NULL, read_t, NULL);
pthread_create(&write_thread, NULL, write_t, NULL);
pthread_join(read_thread, NULL);
pthread_join(write_thread, NULL);
return 0;
}
void *read_t(void *null)
{
int ret;
while (1)
{
pthread_mutex_lock(&mutex);
if (strlen(buf)==0)
{
ret = read(fd_s, buf, BUFSIZE);
if (ret==0)
{
term = 1;
pthread_mutex_unlock(&mutex);
break;
}
if (ret==-1)
{
perror("read");
exit (0);
}
}
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *write_t(void *null)
{
int ret;
while (1)
{
pthread_mutex_lock(&mutex);
if (strlen(buf)!=0)
{
ret = write(fd_d, buf, BUFSIZE);
if (ret==-1)
{
perror("write");
exit (0);
}
bzero(buf, BUFSIZE);
}
pthread_mutex_unlock(&mutex);
if (term)
break;
}
return NULL;
}