2012-03-09 92 views
0


我可能指針問題與fp,因爲我得到(SIGSEGV)錯誤。 但我沒有太多的C經驗,我沒有看到它。結構問題指針

我正在嘗試做什麼。我爲簡單的遊戲做服務器應用程序,我用新線程處理客戶端。我使用函數pthread_create,它有處理函數稱爲handle_client,我需要在一些參數socketdescritpor(它的工作原理)和filedescriptor寫入日誌(可能有問題)。 在我的主要我打開日誌文件,然後我把文件描述符放到我的結構,我得到handle_client函數內的結構,並在這個函數中我想取回日誌文件的文件描述符(fp),以便能夠寫入文件。我使用fflush(fp)在每個fprintf後保存數據,我打開文件一次,然後每個客戶端應該可以寫入文件通過這個描述符,但我可能做了一些壞指針(我的意思是geting fp in和從結構中,我的代碼中有一部分是我執行此操作的。)Thx尋求幫助。

結構

typedef struct 
    { 
     int fd; 
     FILE *fp; //filepointer for logs file 
    } my_thread_context_t; 

主要

int main(int argc, char *argv[]) { 
FILE * fp; 
    fp = fopen("Serverlog.log","w");//delete last file 
    fclose(fp); 
    fp = fopen("Serverlog.log","a+"); 
     my_thread_context_t ctx; 

//bind server 
//listen 

while(1) { 
//accept 

ctx.fp = fp;// add file pointer to structure 
int check = pthread_create(&thread, NULL,handle_client,&ctx); 
//other code 
} 

hadle_client功能

void * handle_client(void * void_context){ 
    my_thread_context_t * context = (my_thread_context_t *) void_context; 

    FILE *fp; //pointer na soubor s logy 
    fp = context->fp;//get the filepointer for logs 

     //other code .. 

} 
+2

您是否嘗試過在調試器中運行程序?它將幫助您查明崩潰的位置,並讓您檢查可幫助您查看可能出錯的變量。 – 2012-03-09 07:10:00

+1

使用'gdb'或其他調試器來知道你的代碼在哪一點失敗。另外爲了隔離錯誤,首先運行可疑的代碼段而不用線程 – phoxis 2012-03-09 07:11:12

+0

通常,它看起來奇怪的程序設計是在一個線程中打開一個文件,然後從另一個線程處理文件。我只是猜測,但取決於您的操作系統的內部工作原理,這可能是原因。嘗試從線程內部打開文件。還要注意像fopen(),fprintf()等函數不是線程安全的,所以你不能有多個使用這些線程的線程。 – Lundin 2012-03-09 07:42:21

回答

2

它看起來像很多線程可以訪問你的my_thread_context_t::fp這正是問題FILE*類型實際上是C庫使用的結構指針(不透明)。當多個線程修改它時,此結構內容可能會被破壞(或不一致)。您必須同步訪問您的my_thread_context_t::fp。我建議在ctx結構中創建互斥鎖(請參閱pthread_mutex_initpthread_mutex_lock,pthread_mutex_unlock)。開始之前每個線程應該鎖定其寫入一個文件,並打開它時,它寫完 - 此puprpose一個單獨的(內置)函數會更好的設計,例如:如果你做這種方式

typedef struct 
{ 
    int fd; 
    pthread_mutex_t mutex; 
    FILE *fp; //filepointer for logs file 
} my_thread_context_t; 

my_thread_context_t ctx; 
fp = fopen("Serverlog.log","a+"); 
pthread_mutex_init(&ctx.mutex); 
ctx.fp = fp; 

inline void write_to_log(my_thread_context_t* pCtx,const char* pcszMessage) 
{ 
    pthread_mutex_lock(&(pCtx->mutex)); 
    /* here write to the log file */ 
    pthread_mutex_unlock(&(pCtx->mutex)); 
} 

,它不僅安全,而且每次寫入後也不必調用fflush (除非希望日誌始終保持同步)。

在所有線程完成後(例如,在所有必需的ptrhead_join s之後),請不要忘記調用pthread_mutex_destroy