我正在学习有关家庭作业的线程,并尝试在我编写的一个简单程序上实现线程。没有线程程序的完美工作,但当我线程两个随机数生成器函数,它返回不正确的结果。结果似乎总是'42‘的两个数字生成器,不知道为什么会是这样。
另外,对于上下文,我只是从线程开始,所以我理解这个程序不需要多线程。我这么做只是为了学习。
谢谢你的帮助!
// struct for vector to use
struct readings {
std::string name;
int data;
};
// random generator for heat value - stores in vector of struct
void gen_heat(std::vector<readings>& storage) {
readings h = {"Heat", rand() % 100 + 1};
storage.insert(storage.begin(), h);
}
// random generator for light value - stores in vector of struct
void gen_light(std::vector<readings>& storage) {
readings l = {"Light", rand() % 100 + 1};
storage.insert(storage.begin(), l);
}
int main() {
// vector of readings struct
std::vector<readings> storage;
srand(time(NULL));
// initialising threads of random generators
std::thread H(gen_heat, std::ref(storage));
std::thread L(gen_light, std::ref(storage));
// waiting for both to finish
H.join();
L.join();
// print values in vec of struct
for (const auto& e : storage) {
std::cout << "Type: " << e.name << std::endl
<< "Numbers: " << e.data << std::endl;
}
// send to another function
smartsensor(storage);
return 0;
}发布于 2022-04-18 14:29:51
由于您有几个线程访问一个相互的资源,在本例中是读取向量,而且其中一些线程正在修改它,因此您需要使对该资源的访问成为独占的。同步访问的方法有很多种;其中一种方法非常简单,而且不涉及互斥对象的使用,其中之一是二进制信号量 (自C++20)。你基本上:
如果线程A试图在其他线程B使用该资源时获取信号量,则线程A将被阻塞,直到资源被释放。
注意,信号量被初始化为1,指示资源是空闲的。一旦一个线程获得了信号量,计数就会下降到0,直到计数返回到1 (在release之后会发生什么),其他线程才能获得它。
#include <cstdlib> // rand
#include <iostream> // cout
#include <semaphore>
#include <string>
#include <thread>
#include <vector>
std::binary_semaphore readings_sem{1};
// struct for vector to use
struct readings {
std::string name;
int data;
};
// random generator for heat value - stores in vector of struct
void gen_heat(std::vector<readings>& storage) {
for (auto i{0}; i < 5; ++i) {
readings_sem.acquire();
readings h = {"Heat", rand() % 100 + 1};
storage.insert(storage.begin(), h);
readings_sem.release();
}
}
// random generator for light value - stores in vector of struct
void gen_light(std::vector<readings>& storage) {
for (auto i{0}; i < 5; ++i) {
readings_sem.acquire();
readings l = {"Light", rand() % 100 + 1};
storage.insert(storage.begin(), l);
readings_sem.release();
}
}
int main() {
// vector of readings struct
std::vector<readings> storage;
srand(time(NULL));
// initialising threads of random generators
std::thread H(gen_heat, std::ref(storage));
std::thread L(gen_light, std::ref(storage));
// waiting for both to finish
H.join();
L.join();
// print values in vec of struct
for (const auto& e : storage) {
std::cout << "Type: " << e.name << std::endl
<< "Numbers: " << e.data << std::endl;
}
}
// Outputs (something like):
//
// Type: Heat
// Numbers: 5
// Type: Light
// Numbers: 83
// Type: Light
// Numbers: 40
// ...本·沃格特评论的最新进展
资源的获取和释放可以使用RAII (资源获取是初始化)来封装,这种机制已经由语言提供。例如:
lock guard来获得它。#include <mutex> // lock_guard
std::mutex mtx{};
// random generator for heat value - stores in vector of struct
void gen_heat(std::vector<readings>& storage) {
for (auto i{0}; i < 5; ++i) {
std::lock_guard<std::mutex> lg{ mtx };
readings h = {"Heat", rand() % 100 + 1};
storage.insert(storage.begin(), h);
}
}https://stackoverflow.com/questions/71912594
复制相似问题