как один поток может быть убит в другом потоке - PullRequest
0 голосов
/ 16 февраля 2011

На самом деле основной сценарий таков: из основного потока запущены два потока. Используя условную переменную, два потока будут работать и спать, а затем вернутся к основному потоку.только один шаблон: из main-> thread1-> thread2-> main.Я написал код для потока C. Он показывает результат, который я хочу иногда, а иногда нет. Например, вывод:

I am in thread 1 
before conditional wait
I am in thread 2
before conditional release
i am again in thread 2
i am again in thread 1
main exits here

Проблема в том, что «главные выходы здесь» не выполняется.Пожалуйста, помогите мне. Следует отметить, что я не могу использовать pthread_join (). Мой код указан ниже

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

pthread_mutex_t gLock;
pthread_cond_t gCondition;

pthread_mutex_t mLock;
pthread_cond_t mCondition;

void initialize()
{
      pthread_mutex_init(&gLock, NULL);
      pthread_cond_init (&gCondition, NULL);
      pthread_mutex_init(&mLock, NULL);
      pthread_cond_init (&mCondition, NULL);

      return;
}

void * threadOne(void * msg)
{
    printf("%s \n",(char*) msg);
    printf("before conditional wait\n");

    pthread_mutex_lock(&gLock);
    pthread_cond_wait(&gCondition,&gLock);
    pthread_mutex_unlock(&gLock);

    printf("i am again in thread 1\n");

    pthread_mutex_lock(&mLock);
    pthread_cond_signal(&mCondition);
    pthread_mutex_unlock(&mLock);

}

void * threadTwo(void * msg)
{
    printf("%s\n",(char*)msg);
    printf("before conditional release\n");
    pthread_mutex_lock(&gLock);
    pthread_cond_signal(&gCondition);
    pthread_mutex_unlock(&gLock);
    printf("i am again in thread 2\n");

}

int main()
{
        pthread_t thread1;
        pthread_t thread2;

        char * msg1="I am in thread 1";
        char * msg2="I am in thread 2";
        initialize();

        pthread_create(&thread1,NULL,threadOne,(void*) msg1);
        pthread_create(&thread2,NULL,threadTwo,(void*) msg2);

        pthread_mutex_lock(&mLock);
        pthread_cond_wait(&mCondition,&mLock);
        pthread_mutex_unlock(&mLock);

        printf("main exits here");

        return 0;
}

1 Ответ

0 голосов
/ 29 июня 2011

Проблема в том, что вы используете переменную условия неправильно. Условная переменная - это просто механизм уведомления, а не флаг. Он не имеет внутреннего состояния, кроме списка потоков, ожидающих в данный момент. Следовательно, если main() фактически не выполняется до вызова pthread_cond_wait(), когда другие потоки вызывают pthread_cond_signal(), то сигнал теряется, и main() будет ждать вечно.

Вам необходимо использовать отдельный флаг, связанный с условной переменной. main() может затем проверить этот флаг и ждать только, если флаг не установлен. Кроме того, он должен проверять этот флаг в цикле, чтобы гарантировать, что обрабатываются «ложные пробуждения», где pthread_cond_wait() возвращает без соответствующего сигнала. То же самое относится к уведомлению между threadOne и threadTwo.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

pthread_mutex_t gLock;
pthread_cond_t gCondition;
int gFlag=0;

pthread_mutex_t mLock;
pthread_cond_t mCondition;
int mFlag=0;

void initialize()
{
    pthread_mutex_init(&gLock, NULL);
    pthread_cond_init (&gCondition, NULL);
    pthread_mutex_init(&mLock, NULL);
    pthread_cond_init (&mCondition, NULL);
}

void * threadOne(void * msg)
{
    printf("%s \n",(char*) msg);
    printf("before conditional wait\n");

    pthread_mutex_lock(&gLock);
    while(!gFlag)
    {
        pthread_cond_wait(&gCondition,&gLock);
    }
    pthread_mutex_unlock(&gLock);

    printf("i am again in thread 1\n");

    pthread_mutex_lock(&mLock);
    mFlag=1;
    pthread_cond_signal(&mCondition);
    pthread_mutex_unlock(&mLock);

}

void * threadTwo(void * msg)
{
    printf("%s\n",(char*)msg);
    printf("before conditional release\n");
    pthread_mutex_lock(&gLock);
    gFlag=1;
    pthread_cond_signal(&gCondition);
    pthread_mutex_unlock(&gLock);
    printf("i am again in thread 2\n");

}

int main()
{
    pthread_t thread1;
    pthread_t thread2;

    char * msg1="I am in thread 1";
    char * msg2="I am in thread 2";
    initialize();

    pthread_create(&thread1,NULL,threadOne,(void*) msg1);
    pthread_create(&thread2,NULL,threadTwo,(void*) msg2);

    pthread_mutex_lock(&mLock);
    while(!mFlag)
    {
        pthread_cond_wait(&mCondition,&mLock);
    }
    pthread_mutex_unlock(&mLock);

    printf("main exits here");

    return 0;
}
...