void thread1() {
std::string str;
while (true) {
{
std::lock_guard<std::mutex> lock(io_mtx);
std::cout << std::endl << "Enter line: ";
}
std::getline(std::cin, str);
std::unique_lock<std::mutex> lock(mtx);
if (str == "exit") break;
if (str.size() > 64 || !std::all_of(str.begin(), str.end(), ::isdigit)) {
{
std::lock_guard<std::mutex> iolock(io_mtx);
std::cerr << "String must include only numbers from 0 to 9 and less then 64 symbols\n";
}
continue;
}
// from my library(it sort and replace some exact symbols
sort_and_replace(str);
buffer.push(str);
cv.notify_one();
}
}
void thread2() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !buffer.empty(); });
std::string str = buffer.front();
buffer.pop();
{
std::lock_guard<std::mutex> iolock(io_mtx);
std::cout << "Processed line: " << str << std::endl;
}
size_t sum = sum_of_digits(str);
std::string sum_str = std::to_string(sum);
if (send(sockfd, sum_str.c_str(), sum_str.size(), 0) < 0) {
{
std::lock_guard<std::mutex> iolock(io_mtx);
std::cerr << "Error.\n";
}
close(sockfd);
connect_to_server();
}
}
}
int main() {
connect_to_server();
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
close(sockfd);
return 0;
}
此代码无法正确将输出显示到控制台,即出现以下输出:
Error connecting to program2, retrying...
Connected to server program2
Enter line: 123
Enter line: Processed line: 3KB1
123
Enter line: Processed line: 3KB1
1234
Enter line: Processed line: KB3KB1
123
Enter line: Processed line: 3KB1
1234
Enter line: Processed line: KB3KB1
我如何修复代码以使输出为:
Enter line: 1234
Processed line: KB3KB1
Enter line: 123
Processed line: 3KB1
我尝试使用lock_guard但它不起作用
你有一场比赛,第一个线程写入
Enter line:
,然后第二个线程写入 Processed line: KB3KB1
,然后用户键入 1234
。
你需要保证下一个
Enter line:
会在Processed line: KB3KB1
发生后发生,你可以使用std::promise<void>
来实现这一点。
#include <thread>
#include <iostream>
#include <mutex>
#include <algorithm>
#include <queue>
#include <future>
#include <string>
std::mutex io_mtx;
std::mutex mtx;
std::condition_variable cv;
struct Message
{
std::promise<void> promise;
std::string message;
};
std::queue<Message> buffer;
void thread1() {
std::string str;
while (true) {
{
std::lock_guard<std::mutex> lock(io_mtx);
std::cout << "Enter line: ";
}
std::getline(std::cin, str);
std::unique_lock<std::mutex> lock(mtx);
if (str == "exit") break;
if (str.size() > 64 || !std::all_of(str.begin(), str.end(), ::isdigit)) {
{
std::lock_guard<std::mutex> iolock(io_mtx);
std::cerr << "String must include only numbers from 0 to 9 and less then 64 symbols\n";
}
continue;
}
std::promise<void> promise;
auto future = promise.get_future();
buffer.push({ std::move(promise),str});
lock.unlock();
cv.notify_one();
future.wait();
}
}
void thread2() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !buffer.empty(); });
auto message = std::move(buffer.front());
buffer.pop();
{
std::lock_guard<std::mutex> iolock(io_mtx);
std::cout << "Processed line: " << message.message << std::endl;
}
message.promise.set_value();
}
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
Enter line: 12345
Processed line: 12345
Enter line: 12345
Processed line: 12345
Enter line: