c - 在c中使用多个线程读取多个文件

标签 c multithreading thread-safety

<分区>

#include <dirent.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <semaphore.h>


int file_index = 0;         // index for array[500];


struct webData {
    char web_names [255];           
};


void *thread(void *wData_element)
{
    struct webData *temp = wData_element;

    FILE *fp; 
    char line[255]="";      // hold each line;
    fp = fopen(temp->web_names, "r");

    if(fp == NULL)
    {
        perror("Error: File open failure.");
    }
    else
    {
        fgets(line,255, fp);
        printf("%s\n", line);
    }
    fclose(fp);
    return NULL;
}

int main(int argc, char const* argv[]) 
{


    DIR * dir_pointer;          // define a dir pointer;
    struct dirent * entry;      // entry under dir;
    //char *dir = "./data/";
    dir_pointer = opendir("./data/"); // assign dir location into dir pointer


    // declare the struct wData array for each file. 
    struct webData wData[500];
    // declare the threads array.
    pthread_t tid_array[500];


    while( (entry = readdir(dir_pointer)) != NULL)
    {

        if(entry->d_type == DT_REG) // avoid the . and .. dir;
        {

            char full_path[255];     
            full_path[0] = '\0';    // initilize the string;

            strcat(full_path, "./data/");  // concatenate file directory;
            strcat(full_path, entry->d_name);    // concatenate filename;
            strcpy(wData[file_index].web_names, full_path); // store file name into web_names array;


            pthread_create(&tid_array[file_index], NULL, thread, &wData[file_index]);



            file_index++;   // increase the file index for next file.


        }


    }


    for(int i=0; i<500; i++)      
    {
        pthread_join(tid_array[i], NULL);
    }


    return 0;
}

对于这个程序:

数据文件夹中有500个文件。

对于每个文件,我创建一个线程来对该文件执行一些操作。

在我迭代所有 500 个文件之后。我加入了所有线程。

我的问题是:

我如何创建 10 个线程,并且每个线程对 50 个文件执行某些操作?

我怎样才能确保每个线程只处理 50 个文件,因为它们是并发运行的?

例如:

线程 1 处理 1-50 个文件

线程 2 处理 51-100 个文件

.

.

.

非常感谢任何相关的来源或示例。

最佳答案

首先为线程声明一个参数结构

typedef struct thread_param_s {
     // each thread will get an array of webData-files
     struct webData* data;
     // number of elements
     int n;    
} thread_param_t;

您为每个线程创建此参数结构,相应地填充它并将其传递给 pthread_create 而不是 wData*

现在你调整你当前的代码

#include <dirent.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <semaphore.h>


int file_index = 0;         // index for array[500];


struct webData {
    char web_names [255];           
};


void *thread(void *param)
{
    thread_param_t* thread_param = (thread_param_t*)param;
    int i;
    // iterate through all files
    for (i = 0; i < thread_param->n; i++) {
        struct webData *temp = thread_param->data + i;

        FILE *fp; 
        char line[255]="";      // hold each line;
        fp = fopen(temp->web_names, "r");

        if(fp == NULL)
        {
            perror("Error: File open failure.");
        }
        else
        {
            fgets(line,255, fp);
            printf("%s\n", line);
        }
    }
    return NULL;
}

int main(int argc, char const* argv[]) 
{


    DIR * dir_pointer;          // define a dir pointer;
    struct dirent * entry;      // entry under dir;
    //char *dir = "./data/";
    dir_pointer = opendir("./data/"); // assign dir location into dir pointer


    // declare the struct wData array for each file. 
    struct webData wData[500];
    // declare the threads array.



    while( (entry = readdir(dir_pointer)) != NULL)
    {

        if(entry->d_type == DT_REG) // avoid the . and .. dir;
        {

            char full_path[255];     
            full_path[0] = '\0';    // initilize the string;

            strcat(full_path, "./data/");  // concatenate file directory;
            strcat(full_path, entry->d_name);    // concatenate filename;
            strcpy(wData[file_index].web_names, full_path); // store file name into web_names array;

            file_index++;   // increase the file index for next file.
            // just fill wData here

        }


    }

    pthread_t tid_array[10];
    thread_param_t thread_param[10];
    int thread_counter = 0;

    // number of files for each thread
    int step = file_index / 10;
    int i;

    // create all threads
    for(i = 0; i < 9; i++)      
    {
       thread_param[i].n = step;
       thread_param[i].data = wData + step * i;

       pthread_create(&tid_array[i], NULL, thread, thread_param + i);
    }
    // the last thread may get more data, because of integer rounding
    thread_param[i].n = file_index - step * i;
    thread_param[i].data = wData + step * i;

    pthread_create(&tid_array[i], NULL, thread, thread_param + i);



    for(int i=0; i<10; i++)      
    {
        pthread_join(tid_array[i], NULL);
    }


    return 0;
}

关于c - 在c中使用多个线程读取多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40836897/

相关文章:

c - 共享内存访问 CUDA 中的垃圾值

C 中 long double 的转换说明符

java - 没有等待线程的信号条件

c# - 将事务范围添加到 Parallel.Foreach

.net - 学习实现线程池-使用autoresetevent时,信号事件丢失

c - 为什么 C 标准不允许您从函数返回值?

c - 关于检查字符串中的数字

multithreading - C++ 11 std::线程段故障

c - C中的多编写器线程安全队列

c++ - 队列内存泄漏