C语言 简单的多线程程序段错误



下面是编写基本多线程程序的尝试,其中每个线程将从日志文件中读取一行(并且不执行任何操作)。某处有一个错误和程序段错误(未生成核心文件)。

如果fgets()readInput()中的fscanf()替换,那么我会看到一个核心文件。回溯是不一致的,在不同的核心文件中给出不同的调用堆栈。

日志文件的内容如下所示:

<num> hello<num>

所有小于 100 的数字

日志文件中大约有 90 个条目。

AFAIK,对于这段代码正在做的事情,我们不需要锁。但我把它放在以后使用(和练习)中。

有人可以指出我在这段代码中的错误吗?

    threads.h
    ---------
    #include "../../include/global.h"
    #include <pthread.h>
    #define MAX_LOGS      101
    #define NUM_THREADS   10 
    /* a single record in log file. Read by thread from input stream (file) */
    typedef struct __thread_data {
            int   time;    /* time stamp */
            char  log[32]; /* short log msg */ 
    } thread_data_t;
    /* heap (implemented by ordered array) storing the logs */
    typedef struct __heap {
            thread_data_t  entry[MAX_LOGS]; 
            int cur_size;   /* used while inserting nodes? */
    } heap_t; 

    add.c
    -----
    #include "../include/threads.h"
    /* Stream from which logs are read (file stream here). Only one thread can
     * read at a time */
    FILE *fp; 
    pthread_mutex_t   fp_lock; 
    /* thread start routine */
    void *readInput(void *arg) 
    {
            char log[40]; 
            /* get lock for file read */
            pthread_mutex_lock(&fp_lock); 
            /* Critical Section; read file */
            if(!feof(fp)) {
                    fgets(log, 40, fp);
            }
            /* release lock */
            pthread_mutex_unlock(&fp_lock); 
            pthread_exit(NULL); 
    }
    int pthread_main() 
    {
            int         i, ret; 
            pthread_t   threads[NUM_THREADS]; 
            pthread_mutex_init(&fp_lock, NULL); 
            fp = fopen("logs.txt", "r"); 
            /* error check */
            for(i=0; i<NUM_THREADS; i++) {
                    if(ret = pthread_create(&threads[i], NULL, readInput, NULL)) {
                            printf("Oops: %sn", strerror(ret));
                            return EXIT_FAILURE; 
                    }
            }
            for(i=0; i<NUM_THREADS; i++) {
                    pthread_join(threads[i], NULL); 
            }
            fclose(fp); 
            return EXIT_SUCCESS; 
    }
    test.c
    -------
    #include "../include/threads.h"
    int main() 
    {
            return pthread_main(); 
    }
    Makefile
    ---------
CC      = gcc
CFLAGS  = -pthread
OBJFLAGS = -o
STDFLAGS = -std=c99 
DBGS    = -ggdb -pthread 
OBJS    = add.o test.o 
HEADERS = include/threads.h 
SOURCES = src/add.c src/test.c 
all: $(OBJS) 
        $(CC) $(OBJFLAGS) th $(OBJS)
        #make clean
$(OBJS): $(SOURCES) $(HEADERS)
        $(CC) -c $(DBGS) $(SOURCES) 
.PHONY: clean 
clean: 
        rm -rf *.o

核心转储的回溯。

#0  0x00007fff88d5b68e in pthread_create ()
(gdb) bt
#0  0x00007fff88d5b68e in pthread_create ()
#1  0x00000001051e0cf8 in pthread_main () at add.c:46
#2  0x00000001051e0dbf in main () at test.c:5
(gdb) list
1       #include "../include/threads.h"
2
3       int main() 
4       {
5               pthread_main(); 
6               return 0; 
7       }
(gdb) info thread
error on line 787 of "/SourceCache/gdb/gdb-1824/src/gdb/macosx/macosx-nat-infthread.c" in function "void print_thread_info(thread_t, int *)": (ipc/send) invalid destination port (0x10000003)
(gdb) info threads
  5 0x00007fff88d47194 in thread_start ()
  4 0x00007fff8a15e122 in __psynch_mutexwait ()
  3 0x00007fff8a15e122 in __psynch_mutexwait ()
  2 0x00007fff88dc242b in flockfile ()
* 1 0x00007fff88d5b68e in pthread_create ()

编辑1:感谢您的所有反馈。我想在原始帖子中保持实际代码简洁。但这是.c.h文件,也是我正在使用的Makefile

编辑2:添加核心的回溯。add.c 中的第 46 行是 pthread_create() 例程。

问题在于fopen。代码正确编译、链接和创建可执行文件。运行它时,它无法打开日志文件,因为它找不到它。我有以下文件/目录结构。@self的评论有助于确定问题所在。

src/
   | Makefile 
   +--include/ 
   |         | threads.h
   |
   +--src/
         | add.c
         | test.c
         | logs.txt 

以下任一方法都可以解决此问题:(a) 更改 make 规则以src目录中生成可执行文件,并在该目录中运行它。(b) 保持原样,但更改fopen以指向src/logs.txt