Пришел я на собеседование и мне задают вопрос: будет ли такой код работать
Thread1:
___ p = 0;
___ запуск Thread2
___ while( p != 1);
Thread2
____ p = 1;
Где определена p - не важно (т.е. память мы не теряем при заканчивание одного из сридов).
Обратите внимание, что mutex'ов и semaphor'ов нет.
Отвечаю, что в принципе будет. Но 1. срид1 будет есть много процессорного времени, 2. В некоторых операционках срид2 вообще не зафурычит (псевдо мультизадачность)
Человек остался не доволен. Т.е. он ожидал ответа что "работать НЕ будет" и объяснения почему.
Вот я уже третий день в непонятках почему же это не будет работать... ????
Даже если мы одновременно обратимся к одной памяти,то к фатальным результатам это не приведет. На логику (в данном примере) не повлияет (одной итерацией больше, одной меньше - не важно).
Может я чего-то не знаю, просветите !
P.S. Относится к виндам (9x, NT). Компилятор, допустим, MS VC v5.0 и выше...
Да, и еще, p в памяти а не в регистрах, т.е. никакой оптимизации и прочих фенечек.
Мультисридинг или обидели меня :(03.11.01 12:36 Автор: z0 <z0> Статус: Member
это как раз один из клевых екзамплов доказывающих что любой язык высокого уровня - собственно все кроме plain assembler - усложняет! а не упрощает как было обещано работу программера
те абстракции которые вводит язык в образ мышления - в данном примере СОДЕРЖИМОЕ_ПЕРЕМЕННОЙ ___p не регистра и не ячейки по адресу а именно ПЕРЕМЕННОЙ - содержат многие вещи в неявном виде причем довольно непростые и они не совпадают с представлениями человека отвлекшегося от машинного кода
Особо не переживай, хотя пример хрестоматийный02.11.01 22:11 Автор: :-) <:-)> Статус: Elderman Отредактировано 03.11.01 01:45 Количество правок: 2
Этот пример рассмотрен у Рихтера, и у него тоже был с ним прокол:
Во втором издании код был без volatile, и подразумевалось, что все работает.
Но в четвертом издании код уже с volatile, и объяняется, почему без него "работа программы просто немыслима".
Мультисридинг или обидели меня :(02.11.01 20:18 Автор: SerpentFly <Vadim Smirnov> Статус: Member Отредактировано 03.11.01 11:32 Количество правок: 1
На самом деле очень существенно как обьявлено p, дело в том что при компиляции без оптимизации все будет работать, но если использовать оптимизацию, то могут появиться проблемы. В частности на компиляторе от MS это работать не будет (надо бы посмотреть как Intel это бы скомпилил). Я честно говоря ожидал что в первом потоке компилятор просто закинет p в регистр и будет этот регистр в цикле проверять. Это типичный случай когда переменная обьявлена без модификатора volatile, на знание которого, а не мультипоточности тебя похоже пытались проверить. Сразу оговорюсь, что при указании переменной p volatile работать этот код будет.
Ради интереса, решил посмотреть что же выдаст компилятор, если volatile не указывать и компилить с оптимизацией, честно скажу сразу бы не подумал, компилятор выдал приблизительно следущее:
cmp p, 1
jz _exit
_loop: jmp _loop
_exit: здесь выходим из потока
То есть компилятор не то что в регистр закинул и из памяти не считывал, он и эту операцию соптимазил, ну а какой в ней смысл? Логично в какой-то степени.
В общем в твоем случае надо было давить на то как обьявлена p, volatile покажет компилятору что переменная может неожиданно изменится независимо от данного потока и он сгенерит правильный код, который будет работать.
IMHO, такие вопросы не вполне коректны, platform&compiler specific, но это уже проблемы тех с кем ты беседовал.
P.S. Действительно, это есть у Рихтера. Я смотрю опросники любят строить на его примерах.
Мультисридинг или обидели меня :(02.11.01 18:39 Автор: Cyril <sc> Статус: Member
Честно говоря не очень разбираюсь в многопоточных приложениях
но может тот чел считал, что запуститься thread1
запустит thread2, тот p=1
процессор переключается на thread1 тот выполняе while
и оба threada завершаются и видимо больше не работают
> Пришел я на собеседование и мне задают вопрос: будет ли > такой код работать > Thread1: >_p = 0;
>_запуск Thread2
>_while( p != 1);
> > Thread2 >__p = 1;
> > Где определена p - не важно (т.е. память мы не теряем при > заканчивание одного из сридов). > Обратите внимание, что mutex'ов и semaphor'ов нет. > > Отвечаю, что в принципе будет. Но 1. срид1 будет есть много > процессорного времени, 2. В некоторых операционках срид2 > вообще не зафурычит (псевдо мультизадачность) > > Человек остался не доволен. Т.е. он ожидал ответа что > "работать НЕ будет" и объяснения почему. > > Вот я уже третий день в непонятках почему же это не будет > работать... ???? > > Даже если мы одновременно обратимся к одной памяти,то к > фатальным результатам это не приведет. На логику (в данном > примере) не повлияет (одной итерацией больше, одной меньше > - не важно). > > Может я чего-то не знаю, просветите ! > > P.S. Относится к виндам (9x, NT). Компилятор, допустим, MS > VC v5.0 и выше... > > Да, и еще, p в памяти а не в регистрах, т.е. никакой > оптимизации и прочих фенечек.