作业要求
代码思想
首先通过一个生成目录和目录下面文件的代码生成要求的目录
之后不同进程通过有名管道进行通信(使用的时候发现有名管道有问题,便用了文件系统做代替,管道实质上来说也就是FIFO的文件),对于判断数据使用共享内存来进行进程间的读取,对于锁,使用信号量,将信号量存于共享内存中,便可以使进程间可读。
代码实现
创建文件目录以及文件代码:
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/wait.h>
#include<fcntl.h>
#include<sys/stat.h>
#include <errno.h>
#include <stdlib.h>
int once_number=1024;
int word_frequency[52]={0};
void CreatFile(char *fp)
{
int write_fp=0;
int flag_Capitalize=0;
int random_number=0;
int *word = (int *)malloc(once_number* sizeof(int));
int test;
int random_word=0;
if((write_fp=open(fp, O_RDWR |O_CREAT,S_IRWXU))==0)
{
printf("can't open %s for write\n",fp);
}
for(int i=0;i<256;i++)
{
for(int j=0;j<once_number;j++)
{
flag_Capitalize=rand()%2;
if(flag_Capitalize==1)
{
random_word=rand()%26;
word_frequency[random_word]+=1;
word[j]=random_word+'A';
//printf("%c=%d\n",word[j],random_word);
}
else
{
random_word=rand()%26;
word_frequency[random_word+26]+=1;
word[j]=random_word+'a';
//printf("%c=%d\n",word[j],random_word+26);
}
}
write(write_fp,word,once_number*sizeof(int));
}
printf("File %s creat done\n",fp);
}
char* join(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);
if (result == NULL) exit (1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
void dir_exit(char *fp)
{
struct stat file_stat;
int ret;
char *dirpath=fp;
ret = stat(dirpath, &file_stat);//检查文件夹状态
if(ret<0)
{
if(errno == ENOENT)//是否已经存在该文件夹
{
ret = mkdir(dirpath, 0775);//创建文件夹
printf("creat dir '/%s'/\n", dirpath);
if(ret < 0)
{
printf("Could not create directory \'%s\' \n",
dirpath);
return EXIT_FAILURE;
}
}
else
{
printf("bad file path\n");
return EXIT_FAILURE;
}
}
}
int main()
{
char *fp="/home/wsk/文档/linuxhomework3/data";
char first[3][10]={{"/1"},{"/2"},{"/3"}};
char second[2][10]={{"/1"},{"/2"}};
char third[10][10]={{"/1.txt"},{"/2.txt"},{"/3.txt"},{"/4.txt"},{"/5.txt"},{"/6.txt"},{"/7.txt"},{"/8.txt"},{"/9.txt"},{"/10.txt"}};
char *a,*b,*c;
struct stat file_stat;
int ret;
int word_frequency_fp=0;
for(int i=0;i<3;i++)
{
a=join(fp,first[i]);
dir_exit(a);
for(int j=0;j<2;j++)
{
b=join(a,second[j]);
dir_exit(b);
for(int z=0;z<10;z++)
{
c=join(b,third[z]);
printf("%s\n",c);
CreatFile(c);
}
}
}
if(( word_frequency_fp=open("/home/wsk/文档/linuxhomework3/word_frequency_origin.txt", O_RDWR |O_CREAT,S_IRWXU))==0)
{
printf("can't open word frequency file for write\n");
}
write(word_frequency_fp,word_frequency,52*sizeof(int));
return 0;
}
线程版
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/wait.h>
#include<fcntl.h>
#include<sys/stat.h>
int fd[10][2];
int fd_empty[10]={0};
int read_pthread_number=5;
int once_number=1024;
int wirte_pthread_number=5;
int loop_number=15360;//3*2*10*256
int loop_number_of_file=256;
int word_frequency[52]={0};
int file_read[3][2][10]={0};
int all_ready_read=0;
pthread_mutex_t mutex_fd_empty = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_word_frequency_file = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_producer=PTHREAD_MUTEX_INITIALIZER;
char* join(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);
if (result == NULL) exit (1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
void produce(char *fp)
{
int read_fp=0;
int *w = (int *)malloc(once_number* sizeof(int));
if((read_fp=open(fp, O_RDONLY |O_CREAT,S_IRWXU))==0)
{
printf("can't open %s for write\n",fp);
}
int fd_number=0;
int flag=0;
int i=0;
int fd_write_number=0;
while(i<loop_number_of_file)
{
flag=0;
//pthread_mutex_lock(&mutex_producer);
pthread_mutex_lock(&mutex_fd_empty);
for(fd_number=0;fd_number<10;fd_number++)
{
if(fd_empty[fd_number]==0)
{
fd_write_number=fd_number;
flag=1;//you
i=i+1;//xie cheng gong le zai jia 1
break;
}
}
if(flag==1)
{
read(read_fp,w,once_number* sizeof(int));
write(fd[fd_write_number][1],w,once_number* sizeof(int));
printf("fd_write_number=%d\n",fd_write_number);
//printf("i=%d\n",i);
//fd_empty[fd_write_number]=i;budui?
fd_empty[fd_write_number]=1;
}
pthread_mutex_unlock(&mutex_fd_empty);
//pthread_mutex_unlock(&mutex_producer);
}
printf("File %s read done\n",fp);
}
void *consumer()
{
int read_word=0;
int flag=0;
int *w = (int *)malloc(once_number* sizeof(int));
int fd_read_number=0;
int j=0;
while(all_ready_read<loop_number)
{
flag=0;
fd_read_number=0;
pthread_mutex_lock(&mutex_fd_empty);
for(j=0;j<10;j++)
{
if(fd_empty[j])
{
flag=1;
fd_read_number=j;
break;
}
}
if(flag==1){
if(read(fd[fd_read_number][0],w,once_number* sizeof(int)))
{
printf("fd_read_number=%d\n",fd_read_number);
for(int i=0;i<once_number;i++)
{
read_word=w[i];
if(read_word-'a'<0)//判断大写字母还是小写字母
{
word_frequency[read_word-'A']+=1;
//printf("%c=%d\n",read_word,read_word-'A');
}
else
{
word_frequency[read_word-'a'+26]+=1;
//printf("%c=%d\n",read_word,read_word-'a'+26);
}
//pthread_mutex_unlock(&mutex_word_frequency);
}
printf("done\n");
all_ready_read=all_ready_read+1;
fd_empty[fd_read_number]=0;
}
}
pthread_mutex_unlock(&mutex_fd_empty);
}
}
void *producer()
{
char *fp="/home/wsk/文档/linuxhomework3/data";
char *a,*b,*c;
char first[3][10]={{"/1"},{"/2"},{"/3"}};
char second[2][10]={{"/1"},{"/2"}};
char third[10][10]={{"/1.txt"},{"/2.txt"},{"/3.txt"},{"/4.txt"},{"/5.txt"},{"/6.txt"},{"/7.txt"},{"/8.txt"},{"/9.txt"},{"/10.txt"}};
for(int i=0;i<3;i++)
{
a=join(fp,first[i]);
for(int j=0;j<2;j++)
{
b=join(a,second[j]);
for(int z=0;z<10;z++)
{
c=join(b,third[z]);
pthread_mutex_lock(&mutex_word_frequency_file);
if(file_read[i][j][z]==0)//多生产者判断该文件是否已经被读取过
{
file_read[i][j][z]=1;
pthread_mutex_unlock(&mutex_word_frequency_file);
produce(c);
}
else
pthread_mutex_unlock(&mutex_word_frequency_file);
}
}
}
}
int main()
{
int i=0;
int word_frequency_fp=0;
for(i=0;i<10;i++)
{
if(pipe(fd[i])<0)
{
printf("pipe %d error",i);
}
fd_empty[i]=0;
}
pthread_t tidproducer[wirte_pthread_number];
pthread_t tidconsumer[read_pthread_number];
int pthread_number2=0;
while(pthread_number2<wirte_pthread_number)
{
pthread_create(&tidproducer[pthread_number2],NULL,producer,NULL);
pthread_number2=pthread_number2+1;
}
pthread_number2=0;
while(pthread_number2<read_pthread_number)
{
pthread_create(&tidconsumer[pthread_number2],NULL,consumer,NULL);
pthread_number2=pthread_number2+1;
}
pthread_number2=0;
while(pthread_number2<wirte_pthread_number)
{
pthread_join(tidproducer[pthread_number2],NULL);
pthread_number2=pthread_number2+1;
}
printf("producer done\n");
pthread_number2=0;
while(pthread_number2<read_pthread_number)
{
pthread_join(tidconsumer[pthread_number2],NULL);
pthread_number2=pthread_number2+1;
}
printf("consumer done\n");
if(( word_frequency_fp=open("/home/wsk/文档/linuxhomework3/word_frequency_after.txt", O_RDWR |O_CREAT,S_IRWXU))==0)
{
printf("can't open word frequency file for write\n");
}
输出比较原始数据和读取数据是否相同
int fd_2=0;
fd_2=open("/home/wsk/文档/linuxhomework3/word_frequency_origin.txt", O_RDWR |O_CREAT,S_IRWXU);
int fd_22[52];
read(fd_2,fd_22,52*sizeof(int));
for(int ww=0;ww<52;ww++)
{
printf("1=%d,2=%d\n",fd_22[ww],word_frequency[ww]);
}
/
write(word_frequency_fp,word_frequency,52*sizeof(int));
return 0;
}
进程版
//生产者
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/wait.h>
#include<fcntl.h>
#include<sys/stat.h>
#include <sys/ipc.h>
#include <linux/futex.h>
#include <sys/mman.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/shm.h>
int fd[10][2];
int fd_empty[10]={0};
int once_number=1024;
int wirte_pthread_number=5;
int loop_number=15360;//3*2*10*256
int loop_number_of_file=256;
int word_frequency[52]={0};
int all_ready_read=0;
int file_read[3][2][10]={0};
int *shm;//指向fd_empty
int shmid;//共享内存标识符
sem_t *shm2;//指向mutex
int shmid2;//共享内存标识符
pthread_mutex_t mutex_word_frequency_file = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_producer=PTHREAD_MUTEX_INITIALIZER;
char first[3][10]={{"/1"},{"/2"},{"/3"}};
char fifo_file[10][50]={{"/home/wsk/文档/linuxhomework3/fifo/fifo0.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo1.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo2.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo3.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo4.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo5.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo6.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo7.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo8.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo9.txt"}};
char* join(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);
if (result == NULL) exit (1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
void produce(char *fp)
{
int read_fp=0;
int *w = (int *)malloc(once_number* sizeof(int));
if((read_fp=open(fp, O_RDONLY |O_CREAT,S_IRWXU))==0)
{
printf("can't open %s for write\n",fp);
}
int fd_number=0;
int flag=0;
int i=0;
int fd_write_number=0;
int fd_fifo=0;
while(i<loop_number_of_file)
{
//int ssss;
//sem_getvalue(shm2,&ssss);
//printf("psem=%d\n",ssss);
sem_wait(shm2);
flag=0;
for(fd_number=0;fd_number<10;fd_number++)
{
if(shm[fd_number]==0)
{
fd_write_number=fd_number;
flag=1;//you
i=i+1;//xie cheng gong le zai jia 1
break;
}
}
if(flag==1)
{
read(read_fp,w,once_number* sizeof(int));
fd_fifo=open(fifo_file[fd_write_number],O_WRONLY);
int wew=write(fd_fifo,w,once_number* sizeof(int));
close(fd_fifo);
printf("write %d\n",wew);
printf("fd_write_number=%d\n",fd_write_number);
shm[fd_write_number]=1;
}
sem_post(shm2);
}
printf("File %s read done\n",fp);
close(read_fp);
}
void *producer()
{
char *fp="/home/wsk/文档/linuxhomework3/data";
char *a,*b,*c;
char first[3][10]={{"/1"},{"/2"},{"/3"}};
char second[2][10]={{"/1"},{"/2"}};
char third[10][10]={{"/1.txt"},{"/2.txt"},{"/3.txt"},{"/4.txt"},{"/5.txt"},{"/6.txt"},{"/7.txt"},{"/8.txt"},{"/9.txt"},{"/10.txt"}};
for(int i=0;i<3;i++)
{
a=join(fp,first[i]);
for(int j=0;j<2;j++)
{
b=join(a,second[j]);
for(int z=0;z<10;z++)
{
c=join(b,third[z]);
pthread_mutex_lock(&mutex_word_frequency_file);
if(file_read[i][j][z]==0)
{
file_read[i][j][z]=1;
pthread_mutex_unlock(&mutex_word_frequency_file);
produce(c);
}
else
pthread_mutex_unlock(&mutex_word_frequency_file);
}
}
}
}
int main()
{
int i=0;
int word_frequency_fp=0;
int creat_file=0;
for(i=0;i<10;i++)
{
if((creat_file=open(fifo_file[i], O_RDWR |O_CREAT,S_IRWXU))==0)
{
printf("errno=%d\n",errno);
printf("pipe %d error\n",i);
}
fd_empty[i]=0;
}
//创建共享内存
shmid = shmget((key_t)2020, sizeof(fd_empty), IPC_CREAT|0666);
if(shmid == -1)
{
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
//将共享内存连接到当前进程的地址空间
shm =(int *)shmat(shmid, 0, 0);
for(int i=0;i<10;i++)
shm[i]=fd_empty[i];
shmid2 = shmget((key_t)2021, sizeof(sem_t), IPC_CREAT|0666);
if(shmid2 == -1)
{
fprintf(stderr, "shmget2 failed\n");
exit(EXIT_FAILURE);
}
//将共享内存连接到当前进程的地址空间
shm2 =(sem_t *)shmat(shmid2, 0, 0);
sem_init(shm2, 1, 1);
pthread_t tidproducer[wirte_pthread_number];
int pthread_number2=0;
while(pthread_number2<wirte_pthread_number)
{
pthread_create(&tidproducer[pthread_number2],NULL,producer,NULL);
pthread_number2=pthread_number2+1;
}
pthread_number2=0;
while(pthread_number2<wirte_pthread_number)
{
pthread_join(tidproducer[pthread_number2],NULL);
pthread_number2=pthread_number2+1;
}
printf("producer done\n");
return 0;
}
//消费者
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/wait.h>
#include<fcntl.h>
#include<sys/stat.h>
#include <sys/ipc.h>
#include <linux/futex.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/sem.h>
#include <sys/shm.h>
int fd[10][2];
int fd_empty[10]={0};
int read_pthread_number=5;
int once_number=1024;
int loop_number=15360;//3*2*10*256
int loop_number_of_file=256;
int word_frequency[52]={0};
int file_read[3][2][10]={0};
int all_ready_read=0;
int *shm;//指向fd_empty
int shmid;//共享内存标识符
sem_t *shm2;//指向mutex
int shmid2;//共享内存标识符
char fifo_file[10][50]={{"/home/wsk/文档/linuxhomework3/fifo/fifo0.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo1.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo2.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo3.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo4.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo5.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo6.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo7.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo8.txt"},{"/home/wsk/文档/linuxhomework3/fifo/fifo9.txt"}};
char* join(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);
if (result == NULL) exit (1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
void *consumer()
{
int read_word=0;
int flag=0;
int *w = (int *)malloc(once_number* sizeof(int));
int fd_read_number=0;
int j=0;
while(all_ready_read<loop_number)
{
//int ssss;
//sem_getvalue(shm2,&ssss);
//printf("csem=%d\n",ssss);
sem_wait(shm2);
flag=0;
fd_read_number=0;
for(j=0;j<10;j++)
{
if(shm[j])
{
flag=1;
fd_read_number=j;
break;
}
// printf("shm[j]=%d\n",shm[j]);
}
if(flag==1){
int fd_fifo = open(fifo_file[fd_read_number],O_RDONLY);
if(read(fd_fifo,w,once_number* sizeof(int)))
{
printf("fd_read_number=%d\n",fd_read_number);
for(int i=0;i<once_number;i++)
{
read_word=w[i];
if(read_word-'a'<0)
{
word_frequency[read_word-'A']+=1;
//printf("%c=%d\n",read_word,read_word-'A');
}
else
{
word_frequency[read_word-'a'+26]+=1;
//printf("%c=%d\n",read_word,read_word-'a'+26);
}
//pthread_mutex_unlock(&mutex_word_frequency);
}
all_ready_read=all_ready_read+1;
shm[fd_read_number]=0;
//close(fd_fifo);
}
close(fd_fifo);
}
sem_post(shm2);
}
}
int main()
{
int word_frequency_fp=0;
shmid = shmget((key_t)2020, sizeof(fd_empty), IPC_CREAT|0666);
if(shmid == -1)
{
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
//将共享内存连接到当前进程的地址空间
shm =(int *)shmat(shmid, 0, 0);
shmid2 = shmget((key_t)2021, sizeof(sem_t), IPC_CREAT|0666);
if(shmid2 == -1)
{
fprintf(stderr, "shmget2 failed\n");
exit(EXIT_FAILURE);
}
//将共享内存连接到当前进程的地址空间
shm2 =(sem_t *)shmat(shmid2, 0, 0);
pthread_t tidconsumer[read_pthread_number];
int pthread_number2=0;
while(pthread_number2<read_pthread_number)
{
pthread_create(&tidconsumer[pthread_number2],NULL,consumer,NULL);
pthread_number2=pthread_number2+1;
}
pthread_number2=0;
while(pthread_number2<read_pthread_number)
{
pthread_join(tidconsumer[pthread_number2],NULL);
pthread_number2=pthread_number2+1;
}
printf("consumer done\n");
if(( word_frequency_fp=open("/home/wsk/文档/linuxhomework3/word_frequency_after2.txt", O_RDWR |O_CREAT,S_IRWXU))==0)
{
printf("can't open word frequency file for write\n");
}
int fd_2=0;
fd_2=open("/home/wsk/文档/linuxhomework3/word_frequency_origin.txt", O_RDWR |O_CREAT,S_IRWXU);
int fd_22[52];
read(fd_2,fd_22,52*sizeof(int));
for(int ww=0;ww<52;ww++)
{
printf("1=%d,2=%d\n",fd_22[ww],word_frequency[ww]);
}
/
write(word_frequency_fp,word_frequency,52*sizeof(int));
return 0;
}
结果
线程版进程版均为5个生产者5个消费者
启动生产文件和文件目录代码
文件结构3210
线程版
启动线程版程序
输出结果,1代表原文件中对应字母的数量,2表示读取文件中对应字母的数量
使用md5比较二个文件内容 结果相同
进程版