我一直在按照创建 POSIX 线程的说明进行操作,并密切关注他们的示例 Pthread 创建和终止。
根据他们的示例,他们将一个长
整数值传递给pthread_create()
,这将导致类似于以下内容的调用:
pthread_create(&thread, NULL, do_something, (long*)testVal);
我要运行的代码的草图是:
#include <iostream>
#include <pthread.h>
using namespace std;
// Simple example class.
class Range {
public:
int start;
int end;
Range(int start_bound, int end_bound) {
start = start_bound;
end = end_bound;
}
void print() {
cout << "\n(" << start << ", " << end << ')';
}
};
void* do_something(void* testVal) {
std::cout << "Value of thread: " << (long)testVal << '\n';
pthread_exit(NULL);
}
int main() {
pthread_t thread;
Range range = Range(1, 2); // What I really want to pass
long testVal = 42; // Let's test
pthread_create(&thread, NULL, do_something, (void*)testVal);
pthread_exit(NULL);
}
这是在一个作业的上下文中,老师希望我们在Linux中使用gcc,所以我使用Windows子系统来Linux这些编译参数:
gcc program.cpp -o program -lstdc++ -lpthread
运行上述程序将输出“线程值:42”。
我的 C 指针体验已经过去了几年,但只是为了好玩,让我们将数据类型从 long
更改为 int
。这会将语句更改为 int testVal = 42
和标准:::cout
错误:从“void*”强制转换为“int”会丢失精度(int)testVal
警告:从不同大小的整数pthread_create(
使用整数数据类型不是我想要做的,但我包括了这个例子,因为我猜想问题是从这里开始复合的。
问题如何将< code>Range
对象传递给< code>pthread_create()?我需要做一些事情,
void* do_something(void* range) {
(Range)range.print();
...
...但是我遇到了一堆类型错误。研究有关传递此值的其他问题并未带来太多清晰度。回来的主要问题是从类型“范围”到类型“void*”的无效转换。我对将 void 指针传递给值与将 void 指针传递给寻址类型之间的区别还不够精通,无法理解出了什么问题。测试指针引用、取消引用和强制转换的各种组合无济于事。
在开始手头的任务之前,您需要解决几个基本问题,即将Range
的实例传递给新线程。
pthread_exit(NULL);
您将在pthread_exit
的文档中找到pthread_exit()
如何终止调用线程的说明。值得注意的是,在您的程序中,不能保证do_something在
调用pthread_exit
之前实际执行。pthread_create
给你的只是一个模糊的promise,即创建一个新的执行线程,并将很快开始开展业务。不能保证它会在pthread_create
返回之前开始运行,也不能保证新线程将在pthread_exit
终止之前运行。
所以,让我们假设你通过某种方式将一个指向range
对象的指针传递给你的do_something
。好吧,当do_something
尝试做某事时,实际的range
对象已经消失了,你有一个指向已销毁对象的指针,使用它变成了未定义的行为。
在您的main
中,
与其修复它,你可以考虑使用
std::线程,而不是POSIX线程,它提供了一个更自然的本机C执行线程实现,可以解决大多数这些问题(如果使用正确)。
void* do_something(void* range) {
(Range)range.print();
...
...但是我遇到了一堆打字错误。
这是因为您的 Range
类不能从指针转换为 void。
问题 如何将范围对象传递给pthread_create()?
通过使用间接寻址pthreadcreate
接受指向任何类型对象的指针。这就是void*
的意思;它可以指向任何类型的对象。传递对象的地址:
Range range = Range(1, 2);
Range* range_ptr = ⦥
pthread_create(&thread, nullptr, do_something, range_ptr);
// or shorter
pthread_create(&thread, nullptr, do_something, &range);
您可以将 void*
静态强制转换为原始指针类型,然后可以通过指针间接访问指向的对象:
void* do_something(void* void_ptr) {
Range* range_ptr = static_cast<Range*>(void_ptr);
range_ptr->print();
请注意,使用间接寻址会给示例带来一个问题:只要线程使用它,指向的对象必须至少处于活动状态。这在您的示例案例中不起作用,因为该对象是 main
中的自动变量,该示例在启动另一个线程后立即终止。一种解决方案是通过加入来等待另一个线程结束:
// pthread_exit(NULL); <-- replace this
pthread_join(thread, nullptr);
这个例子质量不高。它使用重新解释技巧来避免向线程传递整数时的间接寻址,但不应将long
重新解释为void*
>,因为不能保证它们具有相同的大小,而且不在64位Windows中,因此标准不能保证它们的往返转换的有效性。该示例应该使用std::intptr_t
。
P.S .不要在C中使用< code>NULL。
P. P. S.避免在C中使用pthread。取而代之的是std::线程
。
问题内容: 我在php中有对象,每个对象代表一个“项目”以及与之相关的所有信息。 当用户浏览页面时,这些对象应传递给javascript。理想情况下,镜像相同的结构,因此我可以使用Raphael在我的网站上将每个项目及其信息显示为单独的形状。 但是,如何将对象从php转换为javascript? 问题答案: 您可以将PHP对象转换为数组,然后使用JSON函数对其进行编码。之后,从JavaScrip
问题内容: 我正在尝试学习go,并且一开始我想尝试组装一个超级简单的Web服务器来控制iTunes。过去,我已经多次达到这个目的,并认为我可以在这里简单地取消对osascript的调用。 注释掉的“ say 5”命令 确实 起作用。 我收到的回应如下: 我不确定从这里要去哪里,任何方向都将不胜感激。 问题答案: 我明白了 我认为exec.Command(…)如果参数中有空格,则在参数中添加双引号,
问题内容: 这里有角的新手。我试图找出将对象传递给指令时出了什么问题。 这是我的指令: 这是我调用指令的模板: 是一组对象。 当我运行此,日志,而日志罚款的范围,甚至有一个与所有的数据,我找孩子。 我不确定我在这里做错了什么,因为这种确切的方法以前对我有用。 编辑: 我已经用所有必需的代码创建了一个插件:http ://plnkr.co/edit/uJCxrG 如您所见,该作用域在范围中可用,但我
问题内容: 我想知道是否有可能使用jQuery AJAX函数将数组传递给php函数。我有以下作为我的JavaScript 当我尝试执行以下操作时 我在PHP中将其作为“数组”接收。如何正确发送对象,以便PHP函数可以使用它? 问题答案: 从第二个ajax中,您可以根据属性名称访问数据,例如: 是在php中以关联数组转换的js对象
我在示例中看到如何将消息字符串传递给亚马逊 sns sdk 的发布方法。但是,是否有如何将自定义对象作为消息传递的示例?我尝试将“消息结构”设置为“json”,但随后我得到错误。我应该将对象值传递到参数中的哪个位置? 有什么例子吗?
问题内容: 我想将一个对象传递给控制器,并在控制器中检索值。我定义如下: HTML代码: Javascript: 但是我无法在控制器中检索值。它越来越空。 问题答案: 尝试以下操作:-您正在传递对象数组,因此您应该执行HTTPPost而不是HttpGet(这将适用于通过查询字符串发送它的原始类型数组,例如int,strgin等列表)(请记住查询字符串的限制)。尝试使用HTTPPost