Простая многопоточная программа segfault

Ниже приведена попытка написать простую многопоточную программу, где каждый поток будет читать одну строку из файла журнала (и ничего не делает). Где-то есть ошибка и ошибки программы (файл ядра не генерируется).

Если 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

Обратный след основного дампа.

#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: добавление обратного следа ядра. Строка 46 в add.c представляет собой процедуру pthread_create().

1 ответ

Решение

Проблема заключается в fopen, Код компилируется, связывается и правильно создает исполняемый файл. При запуске он не смог открыть файл журнала, так как не смог найти его. У меня есть ниже структура файла / каталога. Комментарий, сделанный @self, помог выявить проблему.

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

Любой из следующих способов решает проблему: (a) Изменение правила make для сборки исполняемого файла в src каталог и запустить его в этом каталоге. (б) Сохраняйте правила как есть, но меняйте fopen указать на src/logs.txt,

Другие вопросы по тегам