IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【操作系统 实验十】----串行查找和并行查找(生产者消费者问题变形) -> 正文阅读

[C++知识库]【操作系统 实验十】----串行查找和并行查找(生产者消费者问题变形)

?

文章目录

?

1. 串行查找 job10/sfind.c

题目

程序 sfind 在文件或者目录中查找指定的字符串,并打印包含该字符串的行,示例如下:

  1. 在文件 file.c 中查找字符串 main
  • 找到包含字符串 main 的行
  • 打印文件名和该行
  1. 在目录 test 中查找字符串 main
  • 假设目录 test 下存在文件
    test/hello/hello.c
    test/world/world.c

  • 对目录 test下的所有文件进行查找

  • 找到包含字符串 main 的行 打印文件名和该行

测试

cp sfind.c file.c
cp sfind.c test/world/world.c
cp sfind.c test/hello/hello.c

9cbe0989d46d4b73a62857a95319ba06.png

1b50dbb3a0e04afe907dda524c542c38.png

代码

#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

题目

功能

  • 功能与 sfind 相同
  • 要求使用多线程完成
  1. 主线程创建若干个子线程
    主线程负责遍历目录中的文件
    遍历到目录中的叶子节点时
    将叶子节点发送给子线程进行处理
  2. 两者之间使用生产者消费者模型通信
    主线程生成数据
    子线程读取数据
    3807b01703104ed18a55a106ce992ee0.png

测试

00a36dd0cb5b4736b1edf54823d8d0f3.png

代码

#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;
}

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-27 17:12:02  更:2022-05-27 17:12:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 23:15:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码