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

时间:2016-11-28 03:48:44

标签: 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

中的文件编号

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

1 个答案:

答案 0 :(得分:3)

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

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;

您为每个线程创建此param-struct,相应地填充它并将其传递到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;
}