我正在为 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 事件有关。
问题似乎是因为当您在开始观看后在同一目录中创建
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
但是,您还有其他问题,例如在多个线程中同时写入同一个文件。我想这只是一个测试,实际上每个文件都会写入不同的文件,所以对于这个测试,我会将命运文件命名为另一个目录中的源。