What would happen if we just activate the DNS lookup without adding the extra synchronization?
size_t N, char **names, struct addrinfo **infos )
for( i = 0; i < N; ++i )
activate ( i )
assert( 0 == getaddrinfo(
names[i], NULL, NULL, &infos[i] ) );
In the above code there is no way to know when all the DNS lookups are done. Using a semaphore is not the only way to do this synchronization. Alternatively, the "main" activity could explicitly wait for all of the lookup activities to finish. But this code is definitely buggy. The application can never be sure that the lookups are done.