pthread_mutex_trylock и pthread_mutex_unlock вызывают ошибку сегментации - PullRequest
0 голосов
/ 17 марта 2012

Мьютекс должен быть разблокирован после отмены потока, чтобы избежать тупика.Поэтому я разработал следующий метод:

// file_a.c
pthread_attr_t attr;
...
rc2 = pthread_attr_init(&attr);
ERR_IF( rc2 != 0 );
rc2 = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ERR_IF( rc2 != 0 );
rc2 = pthread_create(&destroy_thread, &attr, destroy_expired_sessions, NULL);
ERR_IF( rc2 != 0 );
...
pthread_attr_destroy(&attr);

static void *destroy_expired_sessions(void *t)
{
    ...
    (void)t;

    pthread_cleanup_push(cleanup_handler, NULL);
    while (1)
    {
            ... // doing some work here

            sleep(min_timeout);
    }
    pthread_cleanup_pop(0);
}

static void cleanup_handler(void *arg)
{
    (void)arg;

    authSessionListMutexUnlock();
}

// file_b.c
typedef struct
{
    /** Mutex for using this structure. */
    pthread_mutex_t mutex;
    /** The list of Session nodes. */
    cList *list;
} SessionList;

SessionList *globalSessionList = NULL;

...

void authSessionListMutexUnlock()
{
    if (pthread_mutex_trylock(&globalSessionList->mutex) == EBUSY)
        pthread_mutex_unlock(&globalSessionList->mutex);
}

Причина, по которой я здесь использую pthread_mutex_trylock (), состоит в том, чтобы избежать второго pthread_mutex_unlock (), если мьютекс был разблокирован где-то еще.

Однако,Здесь pthread_mutex_trylock () и pthread_mutex_lock () вызвали ошибку сегментации.

Но программа здесь выглядит безобидной, не так ли?

1 Ответ

1 голос
/ 17 марта 2012

Вы забыли инициализировать мьютекс, используя pthread_mutex_init().

Исходя из опыта, использование неинициализированного мьютекса - довольно безопасная ставка для сбоя вашей программы.

Другой вариант - если вы пытаетесь разблокировать мьютекс из другого потока, чем вы его заблокировали. Поведение этой операции не определено.

Редактировать: быстрое замечание о попытке / разблокировке; если мьютекс заблокирован, вы получите EBUSY и разблокируете его; если мьютекс свободен, то при попытке блокировки удастся заблокировать его, и он не будет разблокирован. Другими словами, это переключит состояние блокировки / разблокировки мьютекса. Это действительно так, как вы и хотели?

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