简单的多线程程序段错误

时间:2013-12-28 12:28:43

标签: c multithreading locking pthreads mutex

下面是尝试编写基本的多线程程序,其中每个线程将从日志文件读取一行(并且什么都不做)。某处有一个bug并且程序段错误(没有生成核心文件)。

如果fgets()fscanf()替换为readInput(),我会看到核心文件。 Backtrace不一致,并在不同的核心文件中提供不同的调用堆栈。

日志文件的内容如下:

<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: %s\n", 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

核心转储的Backtrace。

#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 ()

EDIT1:感谢您的所有反馈。我希望在原帖中保持实际代码简洁。但这里是.c.h文件以及我正在使用的Makefile

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

1 个答案:

答案 0 :(得分:1)

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

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

以下任一项都可以解决此问题:(a)更改make规则以在src目录中构建可执行文件并运行该目录。 (b)按原样保留制定规则,但将fopen更改为指向src/logs.txt