gpt4 book ai didi

c++ - 在 C++ 中多线程时与 cout 和 printf 的区别

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:04:07 27 4
gpt4 key购买 nike

一些背景:

我有一个使用 pthreads 的多线程 C++ 程序。该程序是一个酒店预订系统,有 10 位客人(每个人都有自己的线程),一个入住台(1 个线程)和一个退房台(1 个线程)。酒店只有 5 个房间可供客人入住。我在这个程序中使用信号量来强制执行互斥和事件排序。

问题:

这是我的代码(只是需要的部分...)

sem_init(&openRooms, 0, 5);

sem_wait(&openRooms); //waits for there to be an open room at the hotel

cout << "Guest " << guestNumber << " waits for check-in." << endl;

sem_wait(&checkInLine); //waits for an open spot at the check-in desk

酒店有 5 个房间,因此一次可以入住 5 位客人。当我运行程序时,我得到输出(或类似...)

Guest Guest Guest Guest 24 waits for check-in. waits for check-in.1 waits for check-in. 
3 waits for check-in.

看来cout是让多个打印同时运行,这就是为什么连续多次打印“Guest”的原因。

我试过用 printf 这样做,但没有发生同样的问题。在另一个线程可以打印语句之前打印整个语句。

sem_wait(&checkInSt); //Only one person at check in receptionist at a time
printf("Guest %ld goes to the check-in receptionist.\n", my_rank);
currentThreadIn = my_rank; //Rank for receptionist to use in room assignment

输出:

Guest 1 waits for check in.
Guest 3 waits for check in.
Guest 2 waits for check in.
Guest 4 waits for check in.
Guest 0 waits for check in.

为什么会这样? cout 使用了某种错误吗?另外,有什么办法可以避免使用 cout 吗?我可以使用一个额外的信号量来确保 cout 语句在另一个可以打印之前打印,但我正在寻找一种不使用该额外信号量的方法

最佳答案

printf("Guest %ld goes to the check-in receptionist.\n", my_rank);

当您使用 printf 时,您的字符串被格式化为内部缓冲区,然后在单个操作中输出到控制台("Guest 2 waits for check-in.")。

cout << "Guest " << guestNumber << " waits for check-in." << endl;

当您使用 cout 时,您的字符串会分多个部分输出到控制台 - "Guest" , 其次是 guestNumber , 其次是 " waits for check-in." , 其次是 endl .这是因为每次调用 <<运算符的发生就好像它是一个单独的函数调用(它返回对同一 cout 对象的引用以供下一次调用使用)。

因此,尽管写入控制台本身是线程安全的和原子的,但在 cout 中情况下它只是每个单独的子字符串的原子。

不想用的解决方法printf将是 a) 使用信号量或其他锁定机制,或 b) 在使用 stringstream 打印文本之前格式化文本, 然后将其输出为单个字符串。

关于c++ - 在 C++ 中多线程时与 cout 和 printf 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26961023/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com