I have the following function that will run in the thread:
void *dinning_handler(void *arg)
{
t_philo *philo;
struct timeval start;
philo = (t_philo *)arg;
gettimeofday(&start, NULL);
philo->last_meal_time = start;
while (philo->max_eats == -1 || philo->eats < philo->max_eats)
{
print_blue("is thinking", philo->id, get_ts_in_ms());
pthread_mutex_lock(philo->left_fork);
pthread_mutex_lock(philo->right_fork);
print_blue("has taken a fork", philo->id, get_ts_in_ms());
print_green("is eating", philo->id, get_ts_in_ms());
usleep(philo->time_to_eat * 1000);
philo->eats++;
gettimeofday(&philo->last_meal_time, NULL);
pthread_mutex_unlock(philo->left_fork);
pthread_mutex_unlock(philo->right_fork);
print_blue("is sleeping", philo->id, get_ts_in_ms());
usleep(philo->time_to_sleep * 1000);
}
return (NULL);
}
each of the print functions will have the following format:
void print_red(char **msg, int id, long time)
{
ft_printf("\033[1;31m");
ft_printf("%u %d %s\n", time, id, msg);
ft_printf("\033[0m");
}
This generate a race condition leading to write wrong values in the terminal. If I replace ft_print(which is a self implementation that suppose to work the same way of printf) for the original printf it works fine. Why? do printf use mutex before print? how can I fix my code?
EDIT:
Link for ft_printf implementation, it is too big to put it here
POSIX requires
printfto be thread-safe.But a sequence of
printfstatements is not atomic, so you also got lucky.You need to ensure the group of
printfcalls are executed atomically. In this case, the best solution is to combine them into one.As with
printf, you need to make the group of calls toft_printfatomic. Yes, you could use a mutex to achieve this.