/**
* @file queue1_temp1.c
* @brief 多线程文件搜索
* @author zxy
* @contact
* @created 2023-7-16
* @modified 2023-7-19
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <pthread.h>
#define MAX_PATH_LENGTH 1024
#define NUM_THREADS 6
typedef struct {
char path[MAX_PATH_LENGTH];
int file_count;
int dir_count;
pthread_mutex_t count_mutex;
int thread_id;
} ThreadData;
pthread_mutex_t path_mutex;
char search_paths[MAX_PATH_LENGTH][MAX_PATH_LENGTH];
int search_path_count = 0;//已经搜索到的路径数量
int current_search_path = 0;//处理完成的路径数量
int total_folder=0;
int total_file=0;
//进队 写数据
void enqueue_path(const char* path) {
pthread_mutex_lock(&path_mutex);
if (search_path_count < MAX_PATH_LENGTH) {
strcpy(search_paths[search_path_count], path);
search_path_count++;
}
pthread_mutex_unlock(&path_mutex);
}
//出队 读数据
char* dequeue_path() {
pthread_mutex_lock(&path_mutex);
if (current_search_path >= search_path_count)
{
pthread_mutex_unlock(&path_mutex);
return NULL;
}
char* path = search_paths[current_search_path];
current_search_path++;
pthread_mutex_unlock(&path_mutex);
return path;
}
//线程函数
void* search_directory(void* data) {
ThreadData* thread_data = (ThreadData*)data;
char directory_path[MAX_PATH_LENGTH];
int thread_id = thread_data->thread_id;
while (1) {
char* current_path = dequeue_path();
if (current_path == NULL) {
break;
}
strcpy(directory_path, current_path);
DIR* directory;
struct dirent* entry;
directory = opendir(directory_path);
if (directory == NULL) {
perror("无法打开目录");
pthread_exit(NULL);
}
int local_file_count = 0;
int local_dir_count = 0;
while ((entry = readdir(directory)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[MAX_PATH_LENGTH];
snprintf(full_path, sizeof(full_path), "%s/%s", directory_path, entry->d_name);
if (entry->d_type == DT_DIR) {
local_dir_count++;
enqueue_path(full_path);
printf("线程 %d 搜索到目录:%s\n", thread_id, full_path);
} else if (entry->d_type == DT_REG) {
local_file_count++;
printf("线程 %d 搜索到文件:%s\n", thread_id, full_path);
}
}
pthread_mutex_lock(&thread_data->count_mutex);
total_file += local_file_count;
total_folder += local_dir_count;
//thread_data->file_count += local_file_count;
//thread_data->dir_count += local_dir_count;
pthread_mutex_unlock(&thread_data->count_mutex);
closedir(directory);
}
pthread_exit(NULL);
}
int main(int argc,char* argv[])
{
clock_t t2,t1;
double t21;
if(argc != 2)
{
printf("请输出%s的路径\n",argv[0]);
return 0;
}
// 记录当前时间为t1
t1=clock();
const char* start_path = argv[1];
pthread_t threads[NUM_THREADS];//线程标识符 thread_self()
ThreadData thread_data[NUM_THREADS];
pthread_mutex_init(&path_mutex, NULL);
enqueue_path(start_path);
//int thread_ids[NUM_THREADS];
int i;
//
for (i = 0; i < NUM_THREADS; i++) {
//thread_ids[i] = i + 1;
thread_data[i].file_count = 0;
thread_data[i].dir_count = 0;
pthread_mutex_init(&thread_data[i].count_mutex, NULL);
//thread_data[i].thread_id = thread_ids[i];
thread_data[i].thread_id = i + 1;
pthread_create(&threads[i], NULL, search_directory, &thread_data[i]);
}
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
pthread_mutex_destroy(&thread_data[i].count_mutex);//销毁每个结构体中的互斥锁
}
pthread_mutex_destroy(&path_mutex);
// 记录当前时间为t2
t2=clock();
// 计算程序运行时间(s)
t21=((double)(t2-t1))/CLOCKS_PER_SEC;
// 打印每个线程搜索的文件和目录数量
printf("========\n");
// for (i = 0; i < NUM_THREADS; i++) {
// printf("线程 %d 搜索的文件数量: %d\n", thread_data[i].thread_id, thread_data[i].file_count);
// printf("线程 %d 搜索的目录数量: %d\n", thread_data[i].thread_id, thread_data[i].dir_count);
// }
printf("文件夹数量: %d 文件数量: %d\n", total_folder, total_file);
printf("Time: %f s\n", t21);
return 0;
}
7月20白天版本
//---------------------------------------------------------------
//---------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <pthread.h>
#define MAX_PATH_LENGTH 1024
#define NUM_THREADS 64
typedef struct
{
char path[MAX_PATH_LENGTH];
int file_count;
int dir_count;
pthread_mutex_t count_mutex; //线程私有的互斥锁,保护file_count和dir_count的共享资源的访问
int thread_id;
} ThreadData;
pthread_mutex_t path_mutex; //多个线程共享的资源
char search_paths[MAX_PATH_LENGTH][MAX_PATH_LENGTH];
int search_path_count = 0; //已存储的路径数量
int current_search_path = 0; //当前搜索路径的索引位置
int total_folder=0;
int total_file=0;
//进队 写数据
void enqueue_path(const char* path)
{
pthread_mutex_lock(&path_mutex);
//判断已存储的路径数量是否已达到最大限制
if (search_path_count < MAX_PATH_LENGTH)
{
strcpy(search_paths[search_path_count], path);
search_path_count++;
}
//如果已存满则重新开始入队
else
{
search_path_count = 0;
}
pthread_mutex_unlock(&path_mutex);
}
//出队 读数据
char* dequeue_path() {
pthread_mutex_lock(&path_mutex);
//判断是否还有路径可供出队
if (current_search_path >= search_path_count)
{
pthread_mutex_unlock(&path_mutex);
return NULL;
}
char* path = search_paths[current_search_path];
current_search_path++;
pthread_mutex_unlock(&path_mutex);
return path;
}
//线程函数
void* search_directory(void* data)
{
ThreadData* thread_data = (ThreadData*)data;
char directory_path[MAX_PATH_LENGTH];
int thread_id = thread_data->thread_id;
while (1)
{
char* current_path = dequeue_path();
if (NULL == current_path)
{
break;
}
strcpy(directory_path, current_path);
DIR* directory;
struct dirent* entry;
directory = opendir(directory_path);
if (NULL == directory)
{
perror("无法打开目录");
pthread_exit(NULL);
}
int local_file_count = 0;
int local_dir_count = 0;
while ((entry = readdir(directory)) != NULL)
{
if (strcmp(entry->d_name, ".") == 0 || 0== strcmp(entry->d_name, "..") )
{
continue;
}
char full_path[MAX_PATH_LENGTH];
snprintf(full_path, sizeof(full_path), "%s/%s", directory_path, entry->d_name);
if (entry->d_type == DT_DIR)
{
local_dir_count++;
enqueue_path(full_path);
printf("Thread ID:%lu search folder:%s\n",pthread_self(),full_path); //查看每个线程的工作情况
}
else if (entry->d_type == DT_REG)
{
local_file_count++;
printf("Thread ID:%lu search file:%s\n",pthread_self(),full_path); //查看每个线程的工作情况
}
}
pthread_mutex_lock(&thread_data->count_mutex);
total_file += local_file_count; //文件计数
total_folder += local_dir_count; //文件夹计数
pthread_mutex_unlock(&thread_data->count_mutex);
closedir(directory);
}
pthread_exit(NULL);
}
int main(int argc,char* argv[])
{
clock_t t2,t1;
double t21;
int i;
t1=clock(); // 记录时间为t1
if(argc != 2)
{
printf("请输出%s的路径\n",argv[0]);
return 0;
}
if (sizeof(argv[1]) > MAX_PATH_LENGTH)
{
printf("抱歉,您输入的路径过长\n");
return 0;
}
pthread_t threads[NUM_THREADS];
ThreadData thread_data[NUM_THREADS];
pthread_mutex_init(&path_mutex, NULL);
enqueue_path(argv[1]);
for (i = 0; i < NUM_THREADS; i++)
{
thread_data[i].file_count = 0;
thread_data[i].dir_count = 0;
pthread_mutex_init(&thread_data[i].count_mutex, NULL);
//thread_data[i].thread_id = thread_ids[i];
// thread_data[i].thread_id = i + 1;
pthread_create(&threads[i], NULL, search_directory, &thread_data[i]);
}
for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], NULL);
pthread_mutex_destroy(&thread_data[i].count_mutex); //销毁每个结构体中的互斥锁
}
pthread_mutex_destroy(&path_mutex);
t2=clock(); // 记录当前时间为t2
t21=((double)(t2-t1))/CLOCKS_PER_SEC; // 计算程序运行时间(s)
printf("文件夹数量:%d 文件数量: %d\n" , total_folder, total_file);
printf("耗时: %f s\n", t21);
return 0;
}