Немного странно, что переменная fds не глобальная. Как Ваши потоки к ней обращаются?
Уместно внести такое изменение в функции потоков, если Вы не хотите fds глобальной переменной:
Код:
void* thread1_f (arg)
void* arg;
{
int* fds = arg;
/* close (fds [0]); */
/* закомментировано мною - объяснение см. ниже */
int a = 2000;
pthread_mutex_lock (&mutex);
write(fds [1], &a, sizeof (int));
pthread_mutex_unlock (&mutex);
sleep (1);
/* close (fds [1]); */
return NULL;
}
Далее, учитывая то, что это не полноценные процессы (потоки) то когда первая функция-поток закрывает канал для чтения - то она закрывает его в рамках
всего процесса - само собой, это действует и для потоков, порождённых процессом (в случае с fork()'d процессов такой ситуации не наблюдается

- за объяснениями см. man fork). Второй поток ничего не сможет прочитать по этой причине. Правда я не совсем понимаю, откуда у Вас нарисовалось EBADF, там где должен быть EPIPE... Короче, close (fds [0]), close (fd [1]) безопаснее делать в main ().