Простая многопоточная программа 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
,