2015-04-06 35 views
2

我正試圖編寫一個程序,將多個文件備份到名爲.backups的文件夾中。它爲每個文件或子目錄創建一個線程,並且該線程負責複製操作。但它不能正常工作。有時文件不會被複制,有時它們會有0個字節,有時它可以正常工作。它看起來完全是隨機的,我不知道是什麼導致了它。任何人都可以幫我弄明白嗎?線程安全文件副本

// Copies the file from source to destination and returns number of bytes written 
ssize_t copy_file(char* from, char *to) 
{ 
    const int BUFFER_SIZE = 4096; 
    char buffer[BUFFER_SIZE]; 
    ssize_t n; 
    ssize_t written = 0; 
    FILE* file_from = fopen(from, "r"); 
    FILE* file_to = fopen(to, "w"); 

    if (file_from == NULL || file_to == NULL) 
     return -1; 

    while ((n = fread(buffer, 1, BUFFER_SIZE, file_from)) > 0) { 
     if (fwrite(buffer, sizeof(char), n, file_to) != n) 
      return -1; 
     written += n; 
    } 
    return written; 
} 


// Thread responsible for handling the backup of a single file or subdirectory 
void* backup_thread(void* arg) 
{ 
    struct backup_info* info = (struct backup_info*) arg; 
    ssize_t written; 

    written = copy_file(info->file, info->destination); 

    int rc = pthread_detach(pthread_self()); 
    if (rc != 0) 
     exit(EXIT_FAILURE); 

    free(info); 
    return NULL; 
} 

編輯:另外,這是我如何創建每個線程。

struct backup_info* info = malloc(sizeof(struct backup_info)); 


if ((rc = pthread_create(&thread_id, NULL, backup_thread, info)) != 0) 
     fprintf(stderr, "pthread_create() failed (%d): %s", rc, strerror(rc)); 
+0

只要你不使用全局變量,你的函數應該是可重入的。如何使用互斥鎖? – 2015-04-06 01:21:43

+0

我在哪裏添加這個互斥體? – Ryan 2015-04-06 01:27:19

+0

'copy_file'的開始和結束。 – 2015-04-06 01:30:57

回答

0

我發現了一些可能導致您的問題的錯誤。您從未在任何文件上撥打過fclose()。這最終會導致用盡所有文件描述符(在您的線程之間共享)。我不知道這是唯一的錯誤,但你應該做出修復並看看會發生什麼。

+0

增加了fclose(),但仍然無法正常工作。 – Ryan 2015-04-06 04:55:24

+0

@DCJ你創建了多少個線程?另外,你的任何'fopen','fread'或'fwrite'調用都會返回一個錯誤?如果遇到錯誤,您應該嘗試打印某些內容以幫助查找出現問題的地方。 – JS1 2015-04-06 05:18:50

2

主線程如何退出?

如果它剛剛從main()返回,那麼就和調用exit()一樣,並且會導致所有其他線程在他們碰巧正在做的事情中被無情地殺死。

如果您改爲在main()中明確地調用pthread_exit(),那麼分離的線程將被允許在該進程退出之前完成。

還要注意的是exit(EXIT_FAILURE)backup_thread()也有同樣的問題 - 如果該錯誤情況引發,它將立即拆除整個過程。在這裏也可以更好地使用pthread_exit()