我有以下将在线程中运行的函数:

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);
}

每个打印功能将具有以下格式:

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");
}

这会产生竞争条件,导致在终端中写入错误的值.如果我将ft_print(这是一个self 实现,它的工作方式应该与printf相同)替换为原始的printf,它可以很好地工作.为什么?在打印之前,printf是否使用互斥锁?我如何修复我的代码?

编辑:

Link对于ft_print tf实现,它太大了,不能放在这里

推荐答案

如果我将ft_print替换为原始的print f,它工作正常.为什么?

POSIX要求printf才是线程安全的.

printf条语句的序列不是原子的,所以你也很幸运.

您需要确保自动执行包含printf个调用的组.在这种情况下,最好的解决方案是将它们合并为一个.

printf(
   "\033[1;31m"
   "%u %d %s\n"
   "\033[0m",
   time, id, msg
);

我如何修复我的代码?

printf一样,您需要对ft_printf原子进行该组调用.是的,您可以使用互斥锁来实现这一点.

// Lock the mutex here.
ft_printf( "\033[1;31m" );
ft_printf( "%u %d %s\n", time, id, msg );
ft_printf( "\033[0m" );
// Unlock it here.

C++相关问答推荐

有什么方法可以检测SunOS上的SparcWorks吗?

为什么这个select()会阻止?

为什么海湾合作委员会在共享对象中的. init_data的虚拟内存地址之前留出一个空白

找出文件是否包含给定的文件签名

如果实际的syscall是CLONE(),那么为什么strace接受fork()呢?

如何设置指针指向在函数中初始化的复合文字中的整数?

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

GCC预处理宏和#杂注GCC展开

如何在C中引发/处理自定义信号?

为什么该函数不将参数值保存到数据 struct 中?

轮询libusb_pollfd struct 列表的正确方式是什么?

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

C指针概念分段故障

添加函数会 destruct 嵌入式C代码(无IDE)

可以';t从A9G模块拨打电话

GCC认为这是一个VLA是对的吗?

Linux memcpy 限制关键字语法

使用复合文字数组初始化的指针数组

运行以下 C 程序时出现分段错误

如何让 unlinkat(dir_fd, ".", AT_REMOVEDIR) 工作?