如何正确地将参数传递给pthread
How to correctly pass an argument to a pthread
我试图找出一种方法,让我的程序产生两个蜂鸣声在同一时间使用Beep()函数在windows.h库。我决定使用几个pthreads来完成这个任务。然而,我在创建一组尚可的参数时遇到了麻烦。
我对编程很陌生,不太了解type_casting或void*语法/规则/目的。我知道它是指向任意类型数据的指针。我希望尽可能多地了解多线程和void,因为它们看起来非常有用。如果有人能建议一些好的文章或教程(为初学者制作的),我将非常感激。
#include <iostream>
#include <pthread.h>
#include <windows.h>
using namespace std;
void *tone(void *note)
{
double freq;
freq = double(note);
Beep(freq, 5000);
}
int main()
{
double C5 = 523.25;
double D5 = 587.33;
double E5 = 659.25;
double F5 = 698.46;
double G5 = 783.99;
double A5 = 880.00;
double B5 = 987.77;
double C6 = 1046.50;
pthread_t tone1;
pthread_t tone2;
pthread_create(&tone1, NULL, tone, (void *) C5);
}
同时,我希望我的代码张贴正确。我以前只做过一次。
首先,你应该意识到pthread库(又名POSIX线程)是POSIX系统的线程库,它是当今大多数现代操作系统,除了Windows的;但是<windows.h>
是一个非常Windows的头文件,所以你不应该在同一个程序中混合这两个,除非你是针对模拟或兼容层或类似的(例如在Windows上使用Cygwin,或在Linux上使用Wine)开发。
pthread_create()
和Windows的CreateThread()
/_beginthreadex()
都接受一个void*
参数,该参数传递给线程过程。但是,如果你不想传递一个真正的指针值,你就不必这样做了——操作系统把它当作一个不透明的blob,不加修改地传递它。因此,只要要传递的数据不大于指针,就可以在传入时将其强制转换为指针,然后在另一端将其强制转换回来。
例如,如果你想传递一个整数给线程过程:
int theAnswer = 42;
pthread_create(..., &thread_proc, (void *)(intptr_t)theAnswer);
...
void *thread_proc(void *param) {
int theAnswer = (int)(intptr_t)param; // Contains 42
...
}
你的例子传递了一个double
值,它在64位系统上可能与指针的大小相同,所以你可以使用union
;但它肯定会比32位系统上的指针大。
为了传递超过指针值的数据给线程过程,你需要把这些数据放在内存的某个地方,然后传递一个指向这些数据的指针。棘手的部分是管理内存,特别是在使用同一个线程过程创建多个线程的情况下。
一个常见的错误是在堆栈上分配该数据,并在循环中创建几个线程,这些线程的参数指向该堆栈数据。然而,所有这些线程将指向相同的堆栈数据,并且它们最终读取的实际数据成为具有许多未定义行为的大竞争条件。管理内存的正确的方法是为每个线程动态分配内存,然后让新线程负责释放内存。每个线程都有自己的数据副本,没有内存泄漏,也没有竞争条件。
这里有一个例子,无论double
是否大于指针(即32位和64位系统):
// Allocate dynamic memory for the thread parameter. If you want to pass more
// than one value, create a struct instead.
double *theAnswer = new double(42.0);
pthread_create(..., &thread_proc, theAnswer);
...
void *thread_proc(void *param) {
// Order of operations here is important: dereference the value first, then
// free the memory
double *theAnswerPtr = (double *)param;
double theAnswer = *theAnswerPtr;
delete theAnswerPtr;
// theAnswer is now 42.0, use it
...
}
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将参数传递为"const"的奇怪效果
- 如何在 c++ 中将函数作为参数传递?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 使用引用与指针将数组作为参数传递
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 为什么我不能将引用作为 std::async 的函数参数传递
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- Pthread参数传递