Указатель в структуре вопроса - PullRequest
0 голосов
/ 09 марта 2012


У меня, вероятно, проблема с указателем с fp, потому что я получаю (SIGSEGV) ошибку. Но я не очень опытен в Си и не вижу этого.

Что я пытаюсь сделать. Я делаю Серверное приложение для простой игры, я обрабатываю клиентов в новых темах. Я использую функцию pthread_create, она имеет функцию handle с именем handle_client, мне нужно получить в некоторых аргументах socketdescritpor (это работает) и файловый дескриптор для записи журналов (возможно, есть проблема). В моем основном я открываю файл журнала, затем помещаю filedescriptor в мою структуру, я получаю структуру внутри функции handle_client, и в этой функции я хочу получить обратно файловый дескриптор (fp) файла журнала, чтобы умеет писать в файл. Я использую fflush (fp) для сохранения данных после каждого fprintf, открываю файл один раз, и тогда каждый клиент должен иметь возможность записи в файл через этот дескриптор, но я, вероятно, сделал что-то плохое с указателями (я имею в виду получение fp внутри и снаружи структуры есть часть моего кода, где я делаю это действие. Спасибо за помощь.

1007 * структура *

 typedef struct
    {
        int fd;
        FILE *fp; //filepointer for logs file
    } my_thread_context_t;

1010 * Основной *

int main(int argc, char *argv[]) {
FILE * fp;
    fp = fopen("Serverlog.log","w");//delete last file
    fclose(fp);
    fp = fopen("Serverlog.log","a+");
        my_thread_context_t ctx;

//bind server
//listen

while(1) {
//accept

ctx.fp = fp;// add file pointer to structure 
int check = pthread_create(&thread, NULL,handle_client,&ctx);
//other code
}

функция hadle_client

void * handle_client(void * void_context){
    my_thread_context_t * context = (my_thread_context_t *) void_context;

    FILE *fp; //pointer na soubor s logy
    fp = context->fp;//get the filepointer for logs

       //other code ..

}

1 Ответ

2 голосов
/ 09 марта 2012

Похоже, что многие потоки могут получить доступ к вашим my_thread_context_t::fp и , в этом и заключается проблема .Тип FILE* действительно (непрозрачный) указатель на структуру, используемую библиотекой C.Содержимое этой структуры может быть повреждено (или не согласовано), если его изменяет более одного потока.Вы должны синхронизировать доступ к вашему my_thread_context_t::fp.Я бы предложил создать мьютекс (см. pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock) внутри вашей структуры ctx.Каждый поток должен заблокировать его, прежде чем он начнет запись в файл, и разблокировать его, когда закончит запись - отдельная (встроенная) функция для этой цели будет еще лучше, например:

typedef struct
{
    int fd;
    pthread_mutex_t mutex;
    FILE *fp; //filepointer for logs file
} my_thread_context_t;

my_thread_context_t ctx;
fp = fopen("Serverlog.log","a+");
pthread_mutex_init(&ctx.mutex);
ctx.fp = fp;

inline void write_to_log(my_thread_context_t* pCtx,const char* pcszMessage)
{
    pthread_mutex_lock(&(pCtx->mutex));
    /* here write to the log file */
    pthread_mutex_unlock(&(pCtx->mutex));
}

Если вы сделаете этотаким образом, это не только безопасно, но вам также не нужно вызывать fflush после каждой записи (если только вы не хотите, чтобы ваш журнал всегда был синхронизирован).

Не забудьте позвонить pthread_mutex_destroy после завершения всех потоков (например, после всех необходимых ptrhead_join с).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...