【问题标题】:Pointer in struct issue结构问题中的指针
【发布时间】:2012-03-09 07:05:34
【问题描述】:


我可能有 fp 的指针问题,因为我得到 (SIGSEGV) 错误。 但是我在 C 方面的经验并不多,我也看不到。

我正在尝试做的事情。我为简单的游戏做服务器应用程序,我在新线程中处理客户端。我使用函数pthread_create,它有句柄函数handle_client,我需要输入一些参数socketdescritpor(它可以工作)和filedescriptor来写日志(可能有问题)。 在我的主文件中,我打开日志文件,然后将文件描述符放入我的结构中,我在 handle_client 函数中获取结构,在这个函数中我想取回日志文件的文件描述符(fp),成为能够写入文件。我使用 fflush(fp) 在每个 fprintf 之后保存数据,我打开文件一次,然后每个客户端应该能够通过这个描述符写入文件,但我可能对指针做了一些不好的事情(我的意思是得到 fp从结构中进出,有一段我的代码在其中执行此操作。)谢谢帮助。

结构

 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 ..

}

【问题讨论】:

  • 你试过在调试器中运行程序吗?它将帮助您查明崩溃的位置,还可以让您检查有助于您了解可能出现问题的变量。
  • 使用gdb 或其他调试器来了解您的代码在什么时候失败。还要隔离错误,首先在没有线程的情况下运行可疑的代码段
  • 一般来说,在一个线程中打开一个文件,然后从另一个线程处理文件看起来很奇怪。我只是在猜测,但根据您操作系统的内部工作原理,这可能是原因。尝试从线程内部打开文件。另请注意,fopen()、fprintf() 等函数不是线程安全的,因此您不能使用多个线程。
  • 如果您不熟悉 gdb,可以随时查看本教程,假设您在 Linux 中进行开发。 unknownroad.com/rtfm/gdbtut/gdbtoc.html

标签: c file pointers


【解决方案1】:

看起来很多线程都可以访问您的my_thread_context_t::fp这正是问题所在FILE* 类型实际上是指向 C 库使用的结构的(不透明)指针。当多个线程修改它时,此结构内容可能会损坏(或不一致)。您必须同步对您的my_thread_context_t::fp 的访问。我建议在您的ctx 结构中创建一个互斥锁(请参阅pthread_mutex_initpthread_mutex_lockpthread_mutex_unlock)。每个线程都应该在开始写入文件之前锁定它,并在完成写入后解锁它——为此目的的单独(内联)函数将是更好的设计,例如:

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 每次写入后(除非您希望日志始终保持同步)。

不要忘记在所有线程完成后调用pthread_mutex_destroy(例如,在所有必要的ptrhead_joins 之后)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多