?
?
1. 串行查找 job10/sfind.c
题目
程序 sfind 在文件或者目录中查找指定的字符串,并打印包含该字符串的行,示例如下:
- 在文件 file.c 中查找字符串 main
- 在目录 test 中查找字符串 main
测试
cp sfind.c file.c
cp sfind.c test/world/world.c
cp sfind.c test/hello/hello.c
代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
void find_file(char *path,char *target)
{
FILE *file = fopen(path,"r");
char line[256];
while (fgets(line,sizeof(line),file)){
if(strstr(line,target))
printf("%s: %s",path,line);
}
fclose(file);
}
void find_dir(char *path,char *target)
{
DIR *dir = opendir(path);
struct dirent *entry;
while(entry = readdir(dir)){
if(strcmp(entry->d_name,".") == 0)
continue;
if(strcmp(entry->d_name,"..") == 0)
continue;
if(entry->d_type == DT_DIR)
{
//printf("dir %s\n",entry->d_name);
char base[80];
memset(base,'\0',sizeof(base));
strcpy(base,path);
strcat(base,"/");
strcat(base,entry->d_name);
//printf("base %s\n",base);
find_dir(base,target);
}
if(entry->d_type == DT_REG)
{
//printf("file %s\n",entry->d_name);
char base[80];
memset(base,'\0',sizeof(base));
strcpy(base,path);
strcat(base,"/");
strcat(base,entry->d_name);
find_file(base,target);
}
}
closedir(dir);
}
int main(int argc,char *argv[])
{
if(argc!=3)
{
puts("usage: sfind file string");
return 0;
}
char *path = argv[1];
char *string = argv[2];
struct stat info;
stat(path,&info);
if(S_ISDIR(info.st_mode))
find_dir(path,string);
else
find_file(path,string);
return 0;
}
2. 并行查找 job10/pfind.c
题目
功能
- 主线程创建若干个子线程
主线程负责遍历目录中的文件 遍历到目录中的叶子节点时 将叶子节点发送给子线程进行处理 - 两者之间使用生产者消费者模型通信
主线程生成数据 子线程读取数据
测试
代码
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<dirent.h>
#define WORKER_NUMBER 4
#define CAPACITY 40
struct task{
int is_end;
char path[128];
char string[128];
};
struct task buffer[100];
int in=0;
int out=0;
int buffer_is_empty()
{
return in == out;
}
int buffer_is_full()
{
return (in + 1)%CAPACITY == out;
}
pthread_mutex_t mutex;
pthread_cond_t wait_empty_buffer;
pthread_cond_t wait_full_buffer;
struct task get_item()
{
struct task item;
pthread_mutex_lock(&mutex);
while(buffer_is_empty())
{
printf("wait_full\n");
pthread_cond_wait(&wait_full_buffer,&mutex);
}
item = buffer[out];
out = (out+1)% CAPACITY;
pthread_cond_signal(&wait_empty_buffer);
pthread_mutex_unlock(&mutex);
return item;
}
void put_item(struct task item)
{
pthread_mutex_lock(&mutex);
while(buffer_is_full())
{
pthread_cond_wait(&wait_empty_buffer,&mutex);
}
buffer[in]=item;
in = (in+1)%CAPACITY;
pthread_cond_signal(&wait_full_buffer);
pthread_mutex_unlock(&mutex);
}
void find_file(char *path,char *target)
{
FILE *file = fopen(path,"r");
char line[256];
while (fgets(line,sizeof(line),file)){
if(strstr(line,target))
printf("%s: %s",path,line);
}
fclose(file);
}
void *worker_entry(void *arg)
{
while(1){
struct task task;
// printf("in=%d,out=%d\n",in,out);
task=get_item();
if(task.is_end)
{
// printf("in = %d,out = %d\n",in,out);
struct task tm;
tm.is_end=1;
put_item(tm);
break;
}
find_file(task.path,task.string);
}
}
void find_dir(char *path,char *target)
{
DIR *dir = opendir(path);
struct dirent *entry;
struct task buffer;
while(entry = readdir(dir)){
if(strcmp(entry->d_name,".") == 0)
continue;
if(strcmp(entry->d_name,"..") == 0)
continue;
if(entry->d_type == DT_DIR)
{
char base[80];
memset(base,'\0',sizeof(base));
strcpy(base,path);
strcat(base,"/");
strcat(base,entry->d_name);
// printf("base:%s\n",base);
find_dir(base,target);
}
if(entry->d_type == DT_REG)
{
char base[80];
memset(base,'\0',sizeof(base));
strcpy(base,path);
strcat(base,"/");
strcat(base,entry->d_name);
//join array
// printf("file:%s\n",base);
buffer.is_end=0;
strcpy(buffer.path,base);
strcpy(buffer.string,target);
put_item(buffer);
// printf("put_item\n");
break;
}
}
closedir(dir);
}
int isfile(char *path)
{
struct stat buf;
int result;
result = stat(path,&buf);
if(S_IFDIR & buf.st_mode){
return 0;
}else if(S_IFREG & buf.st_mode){
return 1;
}
return -1;
}
int main(int argc,char *argv[])
{
char *path = argv[1];
char *string = argv[2];
if(isfile(path))
{
find_file(path,string);
return 0;
}
pthread_t consumer_tid[WORKER_NUMBER];
// printf("lll\n");
find_dir(path,string);
// printf("hhh\n");
struct task buf;
buf.is_end=1;
put_item(buf);
//create
for(int i=0;i<WORKER_NUMBER;i++)
{
// printf("pthread_create:%d\n",i);
pthread_create(&consumer_tid[i],NULL,worker_entry,NULL);
}
//is_end
// struct task test;
//exit
for(int i=0;i<WORKER_NUMBER;i++)
{
// printf("end\n");
// test = get_item();
// printf("test.is_end = %d\n",test.is_end);
// out--;
pthread_join(consumer_tid[i],NULL);
}
return 0;
}
?
|