2012-03-09 90 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