C C  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Потоки pthread

Тест проверяет не названия функций pthread, а жизненный цикл потоков, передачу аргументов, защиту инвариантов, условные переменные, завершение, гонки и публикацию данных.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. Код читайте построчно: часть заданий проверяет вывод, часть — поиск дефекта, переносимость и безопасное исправление. После завершения откроются объяснения и профиль по 6 темам.
Вопрос 1 из 30
Какой дефект возникает, если всем потокам передать адрес одной переменной цикла?
CC17
for(int i=0;i<4;i++)
  pthread_create(&t[i],NULL,worker,&i);
Вопрос 2 из 30
Как pthread_create сообщает ошибку?
CC17
int rc=pthread_create(&t,NULL,worker,arg);
if(rc) fprintf(stderr,"%s\n",strerror(rc));
Вопрос 3 из 30
Что не так с возвратом адреса локальной переменной из потока?
CC17
void *worker(void *p){
  int result=42;
  return &result;
}
Вопрос 4 из 30
Что гарантирует успешный вызов `pthread_join`?
CC17
void *result=NULL;
int rc=pthread_join(t,&result);
Вопрос 5 из 30
Как корректно обработать ошибку при создании третьего из пяти потоков?
CC17
for(size_t i=0;i<5;i++){
  int rc=pthread_create(&t[i],NULL,worker,&ctx[i]);
  if(rc){ created=i; goto rollback; }
}
Вопрос 6 из 30
Почему `counter++` без синхронизации создаёт гонку данных?
CC17
/* два потока */
for(int i=0;i<100000;i++) counter++;
Вопрос 7 из 30
Какой порядок захвата создаёт возможность взаимной блокировки?
CC17
/* T1 */ lock(A); lock(B);
/* T2 */ lock(B); lock(A);
Вопрос 8 из 30
Почему нельзя читать защищённое поле без мьютекса «только для проверки»?
CC17
if(shared.ready) use(shared.value); /* чтение без m */
Вопрос 9 из 30
Как сократить время удержания мьютекса в этой критической секции?
CC17
pthread_mutex_lock(&m);
send(sock,shared.buf,shared.len,0);
pthread_mutex_unlock(&m);
Вопрос 10 из 30
Что делать, если pthread_mutex_lock вернул ошибку?
CC17
int rc=pthread_mutex_lock(&m);
if(rc!=0) return rc;
Вопрос 11 из 30
Почему ожидание условной переменной помещают в `while`, а не в `if`?
CC17
pthread_mutex_lock(&m);
while(queue_empty())
  pthread_cond_wait(&cv,&m);
item=pop();
pthread_mutex_unlock(&m);
Вопрос 12 из 30
Что делает pthread_cond_wait с мьютексом?
Вопрос 13 из 30
Почему вызов `pthread_cond_signal` без изменения защищённого предиката не создаёт работу для ожидающего потока?
Вопрос 14 из 30
Когда уместен `pthread_cond_broadcast` вместо `pthread_cond_signal`?
Вопрос 15 из 30
Как возникает потерянное пробуждение в этой самодельной схеме?
CC17
pthread_mutex_lock(&m);
bool need_wait = !ready;
pthread_mutex_unlock(&m);

/* pthread_cond_signal(&cv) может выполниться здесь. */

if (need_wait) {
    pthread_mutex_lock(&m);
    pthread_cond_wait(&cv, &m);
    pthread_mutex_unlock(&m);
}
Вопрос 16 из 30
Если `pthread_create` успешно создал joinable-поток, что произойдёт с его ресурсами, если поток никогда не `join` и не `detach`?
CC17
pthread_t t;
pthread_create(&t,NULL,worker,NULL);
/* ни pthread_join, ни pthread_detach */
Вопрос 17 из 30
Почему асинхронная отмена потока особенно опасна?
Вопрос 18 из 30
Как предсказуемо остановить рабочий пул потоков?
CC17
pthread_mutex_lock(&m);
shutdown=true;
pthread_cond_broadcast(&cv);
pthread_mutex_unlock(&m);
Вопрос 19 из 30
Кто должен освободить объект из кучи, полученный через `pthread_join`?
CC17
void *p = NULL;
pthread_join(t, &p);
consume(p);
/* кто завершает владение объектом p? */
Вопрос 20 из 30
Что делать с уже созданными потоками, если инициализация общего ресурса после них не удалась?
Вопрос 21 из 30
Какой санитайзер компилятора предназначен для обнаружения гонок данных в этом коде?
CC17
static int counter;

void *worker(void *arg) {
    (void)arg;
    ++counter;
    return NULL;
}
/* два потока одновременно выполняют worker */
Вопрос 22 из 30
Почему добавление `printf` иногда скрывает гонку данных?
Вопрос 23 из 30
Что полезно логировать при спорном порядке событий?
Вопрос 24 из 30
Как минимизировать воспроизведение гонки?
Вопрос 25 из 30
Почему один успешный запуск не подтверждает отсутствие гонки данных?
CСтресс-запуск
for i in $(seq 1 1000); do ./race_test || break; done
Вопрос 26 из 30
Почему `volatile bool ready` не обеспечивает публикацию общего объекта между потоками?
CC17
shared.data=42;
ready=true; /* volatile */
Вопрос 27 из 30
Что называют ложным разделением кэша?
Вопрос 28 из 30
Как безопасно один раз опубликовать неизменяемую конфигурацию?
Вопрос 29 из 30
Можно ли вызывать обычный `malloc` из обработчика сигнала, прервавшего поток внутри `malloc`?
Вопрос 30 из 30
Какой контракт лучше для общей очереди?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу