函数在 main 中运行良好,但在线程中运行不正常

问题描述 投票:0回答:1

我正在为 Linux 制作一个 C 程序,它应该从其当前目录中获取文件并将它们附加到一个公共文件中。进程必须具有可调整数量的线程,并且线程是永久性的,这意味着它们将在完成执行后等待,以防它们需要再次执行。下面的代码将一个传入文件分配给最快的线程,该线程尝试将内容附加到公共文件。但是,我用来执行此操作的函数“copiar_archivo()”根本不执行;代码跳过对该函数的调用并继续删除文件。我错过了什么?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/inotify.h>

#define EVENT_SIZE  (sizeof (struct inotify_event))
#define BUF_LEN     (1024 * (EVENT_SIZE + 16))
#define NOM_FICH "FICHERO.csv"

void *hilo_func(void *arg);
void copiar_archivo(char *nombre_archivo_x, char *nombre_archivo_y);

int n_hilos = 2;
int fd, wd;

int main(void) {
    pthread_t hilos[n_hilos];
    int i, rc;
    int thread_numbers[n_hilos];

    fd = inotify_init();
    if (fd < 0) {
        perror("Error al inicializar inotify");
        exit(EXIT_FAILURE);
    }

    wd = inotify_add_watch(fd, ".", IN_CREATE);
    if (wd < 0) {
        perror("Error al agregar directorio para observación");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < n_hilos; i++) {
    thread_numbers[i] = i + 1;
        rc = pthread_create(&hilos[i], NULL, hilo_func, &thread_numbers[i]);
        if (rc) {
            perror("Error al crear hilo");
            exit(EXIT_FAILURE);
        }
    }

    for (i = 0; i < n_hilos; i++) {
        rc = pthread_join(hilos[i], NULL);
        if (rc) {
            perror("Error al esperar hilo");
            exit(EXIT_FAILURE);
        }
    }

    inotify_rm_watch(fd, wd);
    close(fd);

    return 0;
}

void *hilo_func(void *arg) {
    int num_hilo = *(int *) arg;
    char buf[BUF_LEN];
    int length, i = 0;

    while (1) {
        length = read(fd, buf, BUF_LEN);
        printf("Hilo %d: AWARE\n", num_hilo);
        if (length < 0) {
            perror("Error al leer evento inotify");
            exit(EXIT_FAILURE);
        }

        while (i < length) {
            struct inotify_event *event = (struct inotify_event *) &buf[i];
            if (event->mask & IN_CREATE) {
                printf("Hilo %d: archivo '%s' creado\n", num_hilo, event->name);
               
                //PROBLEM HERE
char nom_destino[100] = NOM_FICH;
                copiar_archivo(event->name, nom_destino);
               
                sleep(1);
                remove(event->name);
            }
            i += EVENT_SIZE + event->len;
        }
        i = 0;
    }

    pthread_exit(NULL);
}

void copiar_archivo(char *nombre_archivo_x, char *nombre_archivo_y) {
printf("EY, al menos funciona :)");
    FILE *archivo_x, *archivo_y;
    char buffer[1024];
    size_t n;

    archivo_x = fopen(nombre_archivo_x, "rb");
    if (archivo_x == NULL) {
        perror("Error al abrir archivo X");
        exit(EXIT_FAILURE);
    }

    archivo_y = fopen(nombre_archivo_y, "ab");
    if (archivo_y == NULL) {
        perror("Error al abrir archivo Y");
        exit(EXIT_FAILURE);
    }

    while ((n = fread(buffer, 1, sizeof buffer, archivo_x)) > 0) {
        fwrite(buffer, 1, n, archivo_y);
    }

    if (ferror(archivo_x)) {
        perror("Error al leer archivo X");
        exit(EXIT_FAILURE);
    }

    fclose(archivo_x);
    fclose(archivo_y);
}

我尝试在 main 中使用函数“copiar_archivo()”并使用要处理的文件的确切名称,这确实有效。我怀疑它与在线程中使用它有关,或者可能与 inotify 事件有关。

c linux multithreading file inotify
1个回答
0
投票

问题似乎是因为当您在开始观看后在同一目录中创建

FICHERO.csv
时,第二个线程对此做出反应然后删除文件
FICHERO.csv
给人的印象是该功能未执行。

在开始观看之前创建命运文件将修复该部分:

int main(void) {
    pthread_t hilos[n_hilos];
    int i, rc;
    int thread_numbers[n_hilos];
    fclose(fopen(NOM_FICH, "w")); // create empty file before watching

但是,您还有其他问题,例如在多个线程中同时写入同一个文件。我想这只是一个测试,实际上每个文件都会写入不同的文件,所以对于这个测试,我会将命运文件命名为另一个目录中的源。

© www.soinside.com 2019 - 2024. All rights reserved.