Не знаю, нормально ли это, но он компилируется:
Без каких-либо предупреждений? В самом деле? Я предполагаю, что код, который вы компилируете, должен включать все необходимые заголовки (иначе у вас должно быть загружает предупреждений), но если ваш компилятор не может быть убежден, чтобы определить
buggy.c:30:15: warning: ‘arg’ may be used uninitialized in this
function [-Wmaybe-uninitialized]
arg->fd = fd;
^
тогда это не стоит его соли. Действительно, переменная arg
является используемой неинициализированной, и поэтому ваша программа демонстрирует неопределенное поведение.
Но даже если вы исправите это, после чего программа может быть скомпилирована без предупреждений, она все еще не в порядке.
Я - wait () int в parent, но я не знаю, должен ли я также pthread_join
объединять потоки, или это неявно wait()
.
Родительский процесс вызывает wait()
. Это ожидает завершения дочернего процесса, если таковые имеются. Период. Это не имеет значения для поведения дочернего элемента до его завершения.
Кроме того, в программе pthreads основной поток является специальным: , когда он завершается, вся программа завершается, включая все другие потоки. . Таким образом, ваш дочерний процесс страдает от состояния гонки: основной поток завершает работу сразу после создания второго потока, не гарантируя, что другой поток завершает работу первым, поэтому не определено, что, если таковые имеются, поведение второго потока фактически выполняется. Чтобы избежать этой проблемы, да, в дочернем процессе основной поток должен присоединиться к другому, прежде чем завершится.
Однако безопасно ли даже запись в один и тот же файл в двух потоках?
Это зависит - как от обстоятельств, так и от того, что вы подразумеваете под «безопасным». POSIX требует, чтобы функция write()
была поточно-ориентированной, но это не означает, что несколько потоков или процессов, записывающих в один и тот же файл, не могут по-прежнему мешать друг другу, перезаписывая выходные данные друг друга.
Ваш отчасти тем не менее, в особом случае родитель и потомок записывают через одно и то же описание открытого файла в ядре, а потомок унаследовал с ним связь от своего родителя. Согласно POSIX, вы должны увидеть выходные данные обоих процессов (если они есть; см. Выше) в файле. Однако в POSIX нет способа предсказать порядок появления этих выходных данных.
Я запускаю несколько раз, и иногда вывод равен 1) parentchild
, а иногда только 2) parent
, никаких других случаи - я не знаю, почему child не написал так же, как родители ждут этого. Может кто-нибудь объяснить, почему эти выходные данные?
Дочерний процесс может завершиться до того, как его второй поток выполнит свою запись. В этом случае вы увидите только выходные данные родителя, а не ребенка.