7

我正在使用 Kubuntu 12.04、gcc 4.6.3。如果我创建一个 pthread,请使用 fopen64,然后使用 fgets - 它会出现段错误。用 fopen 替换 fopen64 的相同代码 - 它成功了。不创建 pthread - 它成功。那么为什么会失败呢?这是代码:

#include <stdio.h>
#include <pthread.h>
typedef struct threadArgs
{
    char* argsList;
    int argc;
} threadArgs;

void 
threadRun(void *pArg);

int
main(int argc, char* argv[])
{
    int err = 0;
    threadArgs thrArgs;
    pthread_t thrd;  

    if (argc > 1)
    {
        printf("creating thread \n");
        err = pthread_create (&thrd, NULL, (void *) &threadRun, (void *) &thrArgs);
        printf("pthread_create returned: %d \n", err);
        pthread_join(thrd, NULL);
    }
    else
    {
        printf("no thread - just calling func \n");
        threadRun((void*)&thrArgs);
    }
    printf("Exiting main() \n");

    return err;
}

void 
threadRun(void *pArg)
{
    printf("IN the Thread \n");
    char* pStr;
    FILE *pFile = NULL;

    pFile = (FILE*)fopen64("test.txt","r");
    //pFile = (FILE*)fopen("test.txt","r");

    if (pFile==NULL)
    {
        printf("pFile is NULL \n");
    }
    else
    {
        printf("pFile is NOT null \n");
        char line[256];
        pStr = fgets(line, sizeof(line),pFile);
        if (pStr)
        {
            printf("line retrieved: %s \n", line);
        }
        else
        {
            printf("no line retrieved \n");
        }
    }   

    printf("End of pthread run func \n");
    return;
}
4

1 回答 1

5

pthread_create()期望void * (*)(void *)作为线程函数,但您正在传递void (*)(void *).


更新:

您缺少 的原型fopen64(),因此编译器假定int它与FILE*.


更新1:

要使此原型可用(并通过此修复您的初始问题),只需添加:

#define _LARGEFILE64_SOURCE

作为源文件的第一行。

附加编辑:确切地说:_LARGEFILE64_SOURCE需要在ing#define之前编辑#includestdio.h


更新 2:

按照我用来使 suxxer 工作的来源(main.c):

#define _LARGEFILE64_SOURCE

#include <stdio.h>
#include <pthread.h>

typedef struct threadArgs
{
    char* argsList;
    int argc;
} threadArgs;

void *
threadRun(void *pArg);

int
main(int argc, char* argv[]) /* line 16 */
{
    int err = 0;
    threadArgs thrArgs;
    pthread_t thrd;

    if (argc > 1)
    {
        printf("creating thread \n");
        err = pthread_create (&thrd, NULL, threadRun, &thrArgs);
        printf("pthread_create returned: %d \n", err);
        pthread_join(thrd, NULL);
    }
    else
    {
        printf("no thread - just calling func \n");
        threadRun((void*)&thrArgs);
    }
    printf("Exiting main() \n");

    return err;
}

void  *
threadRun(void *pArg)  /* line 40 */
{
    printf("IN the Thread \n");
    char* pStr;
    FILE *pFile = NULL;

    pFile = fopen64("test.txt","r");

    if (pFile==NULL)
    {
        printf("pFile is NULL \n");
    }
    else
    {
        printf("pFile is NOT null \n");
        char line[256];
        pStr = fgets(line, sizeof(line),pFile);
        if (pStr)
        {
            printf("line retrieved: %s \n", line);
        }
        else
        {
            printf("no line retrieved \n");
        }
    }

    printf("End of pthread run func \n");

    return 0;
}

建造者:

$gcc -Wall -g -o main main.c -pedantic -Wextra -std=c99 -pthread 
main.c: In function ‘main’:
main.c:16: warning: unused parameter ‘argv’
main.c: In function ‘threadRun’:
main.c:40: warning: unused parameter ‘pArg’

(没有其他错误或警告)

环境:

$ uname -a
Linux debian-stable 2.6.32-5-amd64 #1 SMP Sun Sep 23 10:07:46 UTC 2012 x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.4.5-8) 4.4.5
[...]
$ ldd main
        linux-vdso.so.1 =>  (0x00007fff466d6000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007f15ccd20000)
        ibc.so.6 => /lib/libc.so.6 (0x00007f15cc9be000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f15ccf4b000)

输出(使用main.c不带\ns as的源test.txt):

$ valgrind ./main 1
==31827== Memcheck, a memory error detector
==31827== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==31827== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==31827== Command: ./main 1
==31827== 
creating thread 
pthread_create returned: 0 
IN the Thread 
pFile is NOT null 
line retrieved: #define _LARGEFILE64_SOURCE #include <stdio.h> #include <pthread.h> typedef struct threadArgs { char* argsList; int argc; } threadArgs; void * threadRun(void *pArg); int main(int argc, char* argv[]) { int err = 0; threadArgs thrArgs; pthread_t thrd; if (a 
End of pthread run func 
Exiting main() 
==31827== 
==31827== HEAP SUMMARY:
==31827==     in use at exit: 568 bytes in 1 blocks
==31827==   total heap usage: 2 allocs, 1 frees, 840 bytes allocated
==31827== 
==31827== LEAK SUMMARY:
==31827==    definitely lost: 0 bytes in 0 blocks
==31827==    indirectly lost: 0 bytes in 0 blocks
==31827==      possibly lost: 0 bytes in 0 blocks
==31827==    still reachable: 568 bytes in 1 blocks
==31827==         suppressed: 0 bytes in 0 blocks
==31827== Rerun with --leak-check=full to see details of leaked memory
==31827== 
==31827== For counts of detected and suppressed errors, rerun with: -v
==31827== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
于 2012-11-09T17:31:34.663 回答