Форум программистов, компьютерный форум CyberForum.ru

_beginthread - Race Condition в отсутствии оного - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
14.03.2012, 13:31     _beginthread - Race Condition в отсутствии оного #1
Неправильно обозвал тему Правильно - WaitForMultipleObject говорит что все потоки завершены, хотя есть ещё работающие.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void
thread(void * param)
{
    task_st * task = (task_st*) param;
    lexical_st * lx = &(task->lx);
    syntax_st * sx = &(task->sx);
    fseek(lx->stream, lx->start_pos,SEEK_SET);
    lex_cut(lx);
    for (;;) {
        t_token tmp = lexical(lx);
        if (tmp.token == TOKEN_END)
            break;
        parser(sx, &tmp);
    }
    task->is_done = 1;
    fclose(lx->stream);
    return;
}
C++
1
2
3
4
5
6
7
8
9
10
11
void
run_tasks(task_st task[], unsigned amount)
{
    HANDLE * threads = (HANDLE*) calloc(amount, sizeof(HANDLE));
    for (unsigned i = 0; i < amount; i++) {
        threads[i] = (HANDLE)_beginthread(thread, STACK_SIZE, &(task[i]));
    }
    WaitForMultipleObjects(amount, threads, TRUE, INFINITE);
    free(threads);
    return;
}
Так я запускаю потоки, которые должны выполнить свою часть работы и завершиться. Однако происходит какая-то ерунда и с увеличением количества потоков все меньший процент запусков происходит удачно. При последовательном запуске потоков с ожиданием завершения предыдущего, все работает нормально. Можно было бы подумать, что случается состояние гонки, но глобальные переменные, если и используются, то только для чтения (даже не переменная, а константный массив), а передаваемая в поток структура task уникальна для каждого потока и более нигде не используется. Самое интересное, что суть в том, что есть ещё не завершенные поток, а функция ожидания говорит, что все завершены. Если же переписать ожидание самому
C++
1
2
3
4
5
6
7
    for(;;) {
        unsigned int i, k = 0;
        for (i = 0; i < amount; i++) {
            k += task[i].is_done;
        }
        if (k == amount) break;
    }
то все работает отлично.
В чем может быть причина такого странного поведения?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.03.2012, 13:31     _beginthread - Race Condition в отсутствии оного
Посмотрите здесь:

C++ Копирование из оного файла в др.
Race Driver GRID
Как убить процесс порожденный _beginthread()? C++
_beginthread в VS 6.0 C (СИ)
CreateThread / _beginthread C++/CLI
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
14.03.2012, 15:12     _beginthread - Race Condition в отсутствии оного #2
DKOI, убийственно неправильная реализация(моё мнение), посмотрите этот топик, там есть живой многопоточный код с 2-мя парами Производитель-Потребитель,
Как после обработки потока запустить его с новым методом?
Самое важное - лучше всего строить код так чтобы поток "сам себя рубил", а не паять ещё "его убивалку" в основном коде. И вообще не увидел у вас абсолютно никакой синхронизации, у вас все потоки живут своей жизнью, введите Критическую секцию(мне кажется так проще всего будет)
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
14.03.2012, 17:49  [ТС]     _beginthread - Race Condition в отсутствии оного #3
Не, потоки сами себя убивают, когда заканчивают выполнение, да и потребителей там нет. Поток на полном самообеспечении. И крит секции не нужны там, потоки не пересекаются в принципе.
А с ожиданием глюк был в выделениях памяти. Там у меня было много потоков, каждый выделял себе постоянно память и в итоге вылетала ошибка, теперь каждый поток имеет собственный кусок выделенной памяти и при необходимости его обновляет. Но я все равно не могу понять, почему это случалось, пеняю на винду
-=ЮрА=-
Заблокирован
Автор FAQ
14.03.2012, 17:58     _beginthread - Race Condition в отсутствии оного #4
Цитата Сообщение от DKOI Посмотреть сообщение
Не, потоки сами себя убивают, когда заканчивают выполнение,
- где _endthread???Они у тебя по твоему желанию умирают или как???
Цитата Сообщение от DKOI Посмотреть сообщение
Но я все равно не могу понять, почему это случалось, пеняю на винду
- вот потому что изоляции потоков не было через секцию вот и могло происходить перекрёстное выделение памяти, лан раз решил хорошо тогда
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
14.03.2012, 18:04  [ТС]     _beginthread - Race Condition в отсутствии оного #5
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- где _endthread???Они у тебя по твоему желанию умирают или как???
МСДН говорит, что _endthread() вызывается сам, когда идет ретурн из рутины, помещенной в тред.
-=ЮрА=-
Заблокирован
Автор FAQ
14.03.2012, 18:19     _beginthread - Race Condition в отсутствии оного #6
Цитата Сообщение от DKOI Посмотреть сообщение
МСДН говорит, что _endthread() вызывается сам, когда идет ретурн из рутины, помещенной в тред.
- где такое написано????!Ты сам должен в теле потока вызвать _endthread, лан делай как тебе проще, работает значит уже хорошо...
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
14.03.2012, 18:24  [ТС]     _beginthread - Race Condition в отсутствии оного #7
You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter to _beginthread or _beginthreadex.
Вот тут написано
http://msdn.microsoft.com/en-us/libr...=VS.71%29.aspx
-=ЮрА=-
Заблокирован
Автор FAQ
14.03.2012, 18:41     _beginthread - Race Condition в отсутствии оного #8
А теперь внимание перевод того что написано
You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter to _beginthread or _beginthreadex. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread.
Вы можете вызвать _endthread или _endthreadex для немедленного завершения процесса, однако данные функции вызываются автоматически когда thread returns делает возврат, да ну и где у тебя возврат???Мы в цикл зашли и крутимся, когда ты из него выходить собираешся верней каким образом
Цитата Сообщение от DKOI Посмотреть сообщение
for (; {
* * * * * * * * t_token tmp = lexical(lx);
* * * * * * * * if (tmp.token == TOKEN_END)
* * * * * * * * * * * * break;
* * * * * * * * parser(sx, &tmp);
* * * * }
хорошо у тебя выход по tmp.token == TOKEN_END как ты собрался менять tmp, у тебя зашло в цикл с начальными параметрами
Цитата Сообщение от DKOI Посмотреть сообщение
lx = &(task->lx);
всё дальше lx можно менять програмно. Допустим, у тебя есть lexical(lx); parser(sx, &tmp); покажи эти функции. У меня серьёзные сомнения что твой поток вообще прекращает работу до конца программы(т.к. parser и lexical скорее всего не меняют параметры твоего потока)...

Добавлено через 8 минут
Цитата Сообщение от DKOI Посмотреть сообщение
что все потоки завершены, хотя есть ещё работающие.
- вот и подумай почему так

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
У меня серьёзные сомнения что твой поток вообще прекращает работу до конца программы(т.к. parser и lexical скорее всего не меняют параметры твоего потока)...
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
14.03.2012, 18:42  [ТС]     _beginthread - Race Condition в отсутствии оного #9
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
* * * * * * * * t_token tmp = lexical(lx);
* * * * * * * * if (tmp.token == TOKEN_END)
* * * * * * * * * * * * break;
lexical возвращает TOKEN_END когда больше нечего ему обрабатывать
а вот и возврат из треда
C++
1
2
3
        task->is_done = 1;
        fclose(lx->stream);
        return;
И все прекрасно завершается. Теперь даже без шаманства. Результаты правильные, вылетов нет.

А lexical читает из файла указанного в одном из полей lx и даже если lx не меняется, файл рано или поздно кончится
-=ЮрА=-
14.03.2012, 18:45
  #10

Не по теме:

Цитата Сообщение от DKOI Посмотреть сообщение
И все прекрасно завершается.
- раз работает правильно почему у тебя есть незавершённые потоки???
Мне тут делать нечего если не хочешь слушать, удачи...

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.03.2012, 18:51     _beginthread - Race Condition в отсутствии оного
Еще ссылки по теме:

Как добиться Race Condition? C Linux
C++ Определить, сколько раз в тексте встречается слово "мир" или сообщить об отсутствии. Вывести текст и результат
Компилятор сообщает об отсутствии точки с запятой в строке int main() { C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DKOI
 Аватар для DKOI
24 / 24 / 1
Регистрация: 08.09.2010
Сообщений: 136
14.03.2012, 18:51  [ТС]     _beginthread - Race Condition в отсутствии оного #11
Уже потоков незавершенных нет, пропали, когда я поправил выделения памяти, я это писал...
Спасибо за дискуссию, удачи
Yandex
Объявления
14.03.2012, 18:51     _beginthread - Race Condition в отсутствии оного
Ответ Создать тему
Опции темы

Текущее время: 16:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru