热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux多线程目录遍历

目录遍历函数#include<systypes.h>#include<sysstat.h>#include<unistd.h>char

目录遍历函数

#include 
#include 
#include 
char *getcwd(char *buf, size_t size);//获取当前目录的绝对路径
DIR *opendir(const char *name);      //获取一个路径的目录流DIR
DIR *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
   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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define CAPACITY 100
#define PRODUCE 30
#define CONSUME 10
#define THREADNUM 300
namespace 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<
                    std::cout<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<"/"<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();
}

推荐阅读
  • Linux 中使用 clone 函数来创建线程
    2019独角兽企业重金招聘Python工程师标准Linux上创建线程一般使用的是pthread库实际上libc也给我们提供了创建线程的函数那就是cloneintclone(i ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 作者一直强调的一个概念叫做oneloopperthread,撇开多线程不谈,本篇博文将学习,怎么将传统的IO复用pollepoll封装到C++类中。1.IO复用复习使用p ... [详细]
  • 主线:设计窗口类注册窗口类产生窗口显示窗口更新窗口消息循环(将消息路由到窗口中去处理)。APPMODUL.CPP源文件被编译链接进入项目,从APPMOD ... [详细]
  • 不知道你是否还记得之前在进程中的信号处理时,提到过阻塞信号集与未决信号集的概念,如果你已经忘记了,请参考《阻塞信号与未决信号》一文回忆一下 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
author-avatar
Fate丶灬小庆_926
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有