将带有结构的参数传递给 pthread
Passing arguments with struct to pthread
如下所示的代码,函数A将传递一些参数并创建一个线程来执行一些计算并将结果存储到ResultPool(全局(中以供以后使用。函数 A将被调用几次,每次它都会传递不同的参数并创建一个新线程。所有thread_id都将存储在全局变量中,在执行结束时,将从ThreadIdPool中检索thread_id并检查线程的完成情况,然后从ResultPool输出结果。下面的示例代码中省略了线程状态检查和输出结果。
我下面的代码是否是线程安全的,特别是对于那些共享数据?我应该添加什么来防止灾难性故障?请告知
IntS threadCnt;
struct ThreadData
{
int td_tnum;
float td_Freq;
bool td_enablePlots;
int td_ifBin;
int td_RAT;
};
typedef struct ThreadData structThreadDt;
void *thread_A(void *td);
map<int, float> ResultPool;
map<int, pthread_t> ThreadIdPool;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread_id[10];
void FunctionA(int tnum, float msrFrequency, bool enablePlots)
{
//Pass the value to the variables.
int ifBin;
int RAT;
/*
Some calculation here and the results are assigned to ifBin and RAT
*/
structThreadDt *td;
td =(structThreadDt *)malloc(sizeof(structThreadDt));
td->td_tnum = tnum;
td->td_Freq = msrFrequency;
td->td_enablePlots = enablePlots;
td->td_ifBin = ifBin;
td->td_RAT = RAT;
threadCnt = threadCnt+1;
pthread_create(&thread_id[threadCnt], NULL, thread_A, (void*) td);
//Store the thread id to be check for the status later.
ThreadIdPool[tnum]=thread_id[threadCnt];
}
void* thread_A(void* td)
{
int ifBin;
int RAT;
BoolS enablePlots;
FloatS msrFrequency;
IntS tnum;
structThreadDt *tds;
tds=(structThreadDt*)td;
enablePlots = tds->td_enablePlots;
msrFrequency = tds->td_Freq;
tnum = tds->td_tnum;
ifBin = tds->td_ifBin ;
RAT = tds->td_RAT;
/*
Do some calculation here with those ifBIN, RAT, TNUM and frequency.
*/
//Store the result to shared variable with mutex lock
pthread_mutex_lock( &mutex2 );
ResultPool[tnum] = results;
pthread_mutex_unlock( &mutex2 );
free(tds);
return NULL;
}
我会改变的事情(试图防止失败(:
使用 std::- thread 和 std::mutex 而不是 pthread,如果您有足够新的C++版本
- 不要使用 malloc/free,而是使用 std::unique_ptr/std::shared_ptr 等(这样可能更安全(
- 确保 std::maps 只有在它们的互斥锁被锁定时才可以访问(例如,创建一个具有更改映射函数的类,这样您就可以确保所有访问都得到适当的保护(
- 如果可以从任何地方访问数据,则将您的共享数据作为全局数据可能是一个问题,因此我会尝试将它们移出全局范围并使用依赖注入或类似机制。(使用 std::thread 等应该会更容易(
我不知道您要解决的确切问题是什么,但是放弃手动线程管理并转向std::future和std::async甚至可能是有意义的。
从发布的代码来看,我认为不需要thread_id
,但是如果您出于某种原因需要它,那么您应该修复threadCnt
。现在,第一次插入时它不以 0 开头。
ResultPool
可以从thread_A
安全地访问,但必须从遍历它的线程正确完成才能获得结果。如果要由不同的线程调用functionA
,则需要将其中的所有全局变量互斥。
如果您没有std::lock_guard
,那么我建议您为互斥体实现您自己的lock_guard,而不是锁定/解锁。
如果您决定使用 c++11,则提供一个示例代码。
#include <iostream>
#include <future>
#include <thread>
#include <vector>
// Dummy
using ResultType = uint64_t;
std::future<ResultType>
FunctionA(int tnum, float msrFrequency, bool enablePlots) {
return std::async(std::launch::async,
[tnum,msrFrequency,enablePlots] () -> ResultType {
// Dummy Calculation
std::cout << "Executing ..." << std::this_thread::get_id() << std::endl;
return tnum + msrFrequency + enablePlots;
});
}
int main () {
std::vector<std::future<ResultType>> results;
results.emplace_back(FunctionA(1,2,3));
results.emplace_back(FunctionA(4,5,6));
results.emplace_back(FunctionA(7,8,9));
// Check results
for (auto &r : results) {
if (r.valid()) {
std::cout << "result is available: " << r.get() << std::endl;
}
}
}
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将参数传递为"const"的奇怪效果
- 如何在 c++ 中将函数作为参数传递?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 使用引用与指针将数组作为参数传递
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 为什么我不能将引用作为 std::async 的函数参数传递
- 传递并访问多个参数到pthread函数
- Pthread参数传递