Difference with cout and printf while multithreading in c++

泪湿孤枕 提交于 2019-12-07 08:44:47

问题


Some background:

I have a c++ program that is multithreaded using pthreads. The program is a hotel reservation system, with 10 guests (each their own thread), a check-in desk (1 thread) and a check-out desk (1 thread). There are only 5 rooms in the hotel that a guest can be in. I am using semaphores to enforce mutual exclusion and event ordering in this program.

Question:

here is my code (Just parts that are needed...)

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

There are 5 guests that are able to be in the hotel at a time, because there are 5 rooms. When I run the program, I get the output (or something like...)

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

It seems that cout is letting multiple prints be run at the same time, which is why "Guest" is printed multiple times in a row.

I have tried doing this with printf, and the same issue doesn't happen. The entire statement is printed before another thread can print the statement.

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

Output:

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.

Why does this happen? Is there some sort of bugger that cout uses? Additionally, is there any way to avoid this using cout? I could use an additional semaphore to ensure that the cout statement prints before another can print, but I'm looking for a way without using that additional semaphore


回答1:


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

When you use printf, your string is formatted into an internal buffer and then output to the console in a single operation ("Guest 2 waits for check-in.").

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

When you use cout, your string is output to the console in multiple parts - "Guest", followed by guestNumber, followed by " waits for check-in.", followed by endl. This is because each call to the << operator takes place as if it were a separate function call (it returns a reference to the same cout object for the next call to use).

So although writing to the console itself is thread-safe and atomic, in the cout case it's only atomic for each separate sub-string.

The solution if you don't want to use printf would be to a) use a semaphore or other locking mechanism, or b) format the text before printing it using stringstream, and then output it as a single string.




回答2:


The same results are also found by me. Printf always works. I don't think there is any way to make cout "thread safe" unless you make a lock. If you have to use stream to deal with strings, consider the following code:

ss << "Hello World! Thread ID, " << tid << endl;
printf("%s",ss.str().c_str());


来源:https://stackoverflow.com/questions/26961023/difference-with-cout-and-printf-while-multithreading-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!