#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
中的文件编号
非常感谢任何相关的来源或示例。
答案 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;
}