Linux 多线程目录遍历
来源:互联网 发布:维棠flv下载器 mac 编辑:程序博客网 时间:2024/06/05 20:46
目录遍历函数
#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>char *getcwd(char *buf, size_t size);//获取当前目录的绝对路径DIR *opendir(const char *name); //获取一个路径的目录流DIRDIR *fdopendir(int fd); //功能同上,只是路径换成文件描述符struct dirent *readdir(DIR *dirp); //读取目录流中的一个目录struct dirent{ ino_t d_ino; /* inode number */ char d_name[256]; /* filename */};char* dirname(char* pathname); //获取路径的父目录char* basename(char* pathname); //获取文件名int stat(const char *path, struct stat *buf);//将当前文件的信息放入stat结构体中struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for file system I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */};
目录遍历流程
- 首先通过 getcwd(NULL,0)获取当前目录的绝对路径
char *getcwd(char *buf, size_t size);
- 然后用目录指针DIR* 返回打开目录后的目录指针
DIR *opendir(const char* path);
- 用struct dirent* 返回目录的具体信息的指针
struct dirent *readdir(DIR *dirp);;
- 用stat函数提取文件的具体信息
int stat(const char *path, struct stat *buf);
- 获取路径的父目录,和当前文件名
#include<libgen.h> char* dirname(char* pathname); char* basename(char* pathname);
目录解析步骤流程
多线程控制函数
- 函数
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);int pthread_cond_broadcast(pthread_cond_t *cond);int pthread_cond_signal(pthread_cond_t *cond); int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);
- 编写多线程启动类的时候需要把启动线程的类和真正处理任务的线程类分离,用工作线程类的对象指针来启动线程函数
pthread_t start(Thread_run* arg){ arg->set_info(info); pthread_create(&tid,NULL,thread_func,(void*)arg); return tid;}static void* thread_func(void* obj){ pthread_detach(pthread_self()); Thread_run* obj1=(Thread_run*)obj; obj1->run();}
代码案例
线程池代码
#include <unistd.h>#include <pthread.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <queue>#include <iostream>#include <sstream>#include <fstream>#include <cstdio>#include <cstdlib>#include <string.h>#define CAPACITY 100#define PRODUCE 30#define CONSUME 10#define THREADNUM 300namespace FACTORY{ struct Control { Control() { pthread_mutex_init(&mutex,NULL); pthread_cond_init(&cond,NULL); } void lock() { pthread_mutex_lock(&mutex); } void unlock() { pthread_mutex_unlock(&mutex); } void wait() { pthread_cond_wait(&cond,&mutex); } void notify() { pthread_cond_broadcast(&cond); } pthread_mutex_t mutex; pthread_cond_t cond; std::queue<std::string> work_queue; int unfinished; std::string search; }; class Thread_run { public: void set_info(Control* m_info) { info=m_info; } int in_file(const char* file)/*查询词是否包含在文件中*/ { std::ifstream fin(file); std::string line; while(getline(fin,line)) { if(line.find(info->search)!=std::string::npos) { return 1; } } fin.close(); return 0; } void put_dir(const char* task)/*将解析的目录放入工作队列*/ { std::string p_task(task); info->lock(); (info->work_queue).push(p_task); info->unfinished++; info->unlock(); } void get_dir(std::string& task)/*从工作队列取出目录*/ { info->lock(); while((info->work_queue).empty()) { info->wait(); } task=(info->work_queue).front(); (info->work_queue).pop(); info->notify(); info->unlock(); } void mod_unfinished()//解析任务完成,unfinished减1 { info->lock(); if(--info->unfinished==0) { std::cout<<"task is over !"<<std::endl; _exit(0); } info->unlock(); info->notify(); } void handle_reg(std::string& task) { if(in_file(task.c_str())) { //std::cout<<dirname(task.c_str())<<std::endl; std::cout<<basename(task.c_str())<<std::endl; } mod_unfinished(); } void handle_dir(const std::string& task) { DIR* dir; struct dirent* pent; dir=opendir(task.c_str()); while((pent=readdir(dir))!=NULL) { if(strcmp(".",pent->d_name)==0||strcmp("..",pent->d_name)==0) { continue; } std::stringstream ss; ss<<task<<"/"<<pent->d_name; put_dir(ss.str().c_str()); } mod_unfinished(); } void handle_other(const std::string& task) { mod_unfinished(); } void dir_analysis(std::string& task) { struct stat my_stat; bzero(&my_stat,sizeof(my_stat)); if(lstat(task.c_str(),&my_stat)==-1)//对取到的目录进行解析,解析失败任务unfinished也要减1 { perror("lstat"); mod_unfinished(); return; } if(S_ISREG(my_stat.st_mode))//如果是普通文件查找是否包含查询词 { handle_reg(task); } else if(S_ISDIR(my_stat.st_mode))//目录,解析后重新将目录流中的目录放入工作队列 { handle_dir(task); } else { handle_other(task);//直接将unfinished减掉1 } } void run() { while(1) { std::string task; get_dir(task); dir_analysis(task); } } private: Control* info; }; class Factory { public: Factory(std::string m_search,std::string src_path):info(new Control()),handle() { start_flag=0; info->search=m_search; (info->work_queue).push(src_path); } void on() { if(start_flag==1) { return; } start_flag==1; pthread_t recover[THREADNUM]; for(int index=0;index!=THREADNUM;index++) { recover[index]=start(&handle); } for(int index=0;index!=THREADNUM;index++) { pthread_join(recover[index],NULL); } } pthread_t start(Thread_run* arg) { arg->set_info(info); pthread_create(&tid,NULL,thread_func,(void*)arg); return tid; } static void* thread_func(void* obj) { pthread_detach(pthread_self()); Thread_run* obj1=(Thread_run*)obj; obj1->run(); } private: pthread_t tid; int start_flag; Control* info; Thread_run handle; };}
测试函数代码:
#include "dir_scan.hpp"int main(int argc,char** argv){ FACTORY::Factory* str_search=new FACTORY::Factory(argv[1],argv[2]); str_search->on();}
0 0
- Linux 多线程目录遍历
- linux下遍历目录
- linux 目录递归遍历
- Linux中遍历目录
- Linux中遍历目录
- linux 目录遍历
- linux 目录遍历示例
- win/linux遍历目录
- linux下遍历目录
- linux下遍历目录
- linux c++有序遍历目录
- linux 遍历打印目录树
- linux遍历目录C语言
- linux遍历目录及其子目录
- linux目录操作及递归遍历目录
- linux用c语言来遍历目录
- linux C 遍历目录及其子目录
- linux下遍历目录树方法总结
- jva反射详解
- 剑指offer-43 扑克牌的顺子
- POJ 3304 Segments
- 生动形象的Eclipse快捷键整理,来源tank真的很棒!
- 重载-参数含有设置默认值
- Linux 多线程目录遍历
- 移动大数据管理平台实践
- Apache Qpid:一个AMQP的开源实现
- Mac OS X 10.10上的SIP Server的安装和配置(kamailio)
- PHP笔记
- Friend(1719)
- Unity3D中与Android通信
- IKE创建SA步骤
- js 获取3天前的时间