If the consumer of the data was also the creator of the threads working on it, it can simply pthread_join
them all and be sure they are finished. Otherwise, the canonical way to do this would be with a mutex and condition variable in the data structure, and a "data is complete" predicate based on the contents of the data structure. The consumer would wait on the condition variable, and the threads producing the data would signal, after updating the data on which the predicate depends while holding the mutex.
There are ways to achieve the same thing with semaphores (e.g. have each producer post the semaphore once, and the consumer wait N
times, where N
is the number of producers), but this type of design requires your consumer to know more details (like how many producers there are) that might not be its business to know.