读完这个帖子:How to return a value from thread in C关于如何从我测试过的pthread返回一个整数值,看看它是否适用于double,但事实并非如此。有没有办法从pthread进程返回double,long或一个字符串,如原始线程中所描述的那样,而不是返回整数42?
如果是,如何?
如果我有一个10个位置的静态数组和每次修改不同位置的10个pthreads,我会遇到麻烦吗? 例如,“线程0仅修改数组[0],线程1仅修改数组[1],依此类推”。
答案 0 :(得分:4)
线程只需为您希望它返回的结果动态分配内存:
void *myThread(void*)
{
double* result = (double*) malloc(sizeof(double));
*result = 42.0;
return result;
}
无论应该收集什么结果,取消引用使用适当的强制转换返回的指针(毕竟这是带有void*
的C),然后释放内存:
// calling thread (or whatever will collect the value)
void* thread_result;
int err = pthread_join( thread_handle, &thread_result);
double dbl = *(double*) thread_result;
free(thread_result);
作为替代方案,无论创建线程的是什么,都可以传递指向线程应该将结果放在线程的void*
参数中的指针(如果线程需要的不仅仅是那个位,那么可能作为结构的一部分)信息)。如果你有理由避免这种情况,这可能会让你避免动态内存分配,但它可能会使数据的所有权和生命周期变得更加复杂。
答案 1 :(得分:2)
这些只是将Steve Jessop's C solution改编成C ++。这些玩具示例(注意缺少错误检查)使用模板来明确如何更改代码以使用除double
之外的某些类型。例如,如果在完成工作后需要返回多个值,则double
可以替换为class
类型。在实践中,基类和模板可能会被删除,而work()
MyWorker
方法将由调用者直接调用,而不是通过虚拟方法调用。
首先,使用pthread
:
#include <iostream>
#include <pthread.h>
class WorkerBase {
protected: virtual ~WorkerBase () {}
public: virtual void * work () = 0;
};
template <typename T>
struct Worker : public WorkerBase { T result; };
extern "C" void *invoke_worker (void *arg) {
return static_cast<WorkerBase *>(arg)->work();
}
struct MyWorker : public Worker<double> {
void * work () {
result = 4.2;
return 0;
}
};
int main () {
pthread_t t;
MyWorker w;
pthread_create(&t, 0, invoke_worker, &w);
pthread_join(t, 0);
std::cout << "result: " << w.result << std::endl;
return 0;
}
其次,使用C ++ 11 std::thread
:
#include <iostream>
#include <thread>
class WorkerBase {
protected: virtual ~WorkerBase () {}
public: virtual void work () = 0;
static void invoke (WorkerBase *w) { w->work(); }
};
template <typename T>
struct Worker : public WorkerBase { T result; };
class MyWorker : public Worker<double> {
void work () { result = 4.2; }
};
int main () {
MyWorker w;
std::thread t(MyWorker::invoke, &w);
t.join();
std::cout << "result: " << w.result << std::endl;
return 0;
}
你的帖子中还有另一个我错过的问题:
如果我有一个10个位置的静态数组和每次修改不同位置的10个pthreads,我会遇到麻烦吗?
这是否会给您带来麻烦可能取决于数组元素类型和您的硬件架构。在实践中,我没有发现这是x86体系结构中存在的问题,因为数组元素在机器字边界上对齐。
答案 2 :(得分:1)
我认为这太难了。我不使用来自cstdlib的malloc(size_t),而只是新的。 以下示例将参数作为结构传递给线程,并返回另一个结构。要显示它可以采用任何变量类型我也使用字符串向量...
#include <iostream>
#include <pthread.h>
#include <vector>
#include <string.h>
#include <cstdlib>
using namespace std;
struct thread_data {
int number;
vector<string> strings;
thread_data (){}
thread_data(int nr) {
number = nr;
strings.push_back("aba\n");
}
};
struct thread_return_data {
int S;
vector<string> R;
};
void *Thread (void *threadarg) {
thread_return_data *R = new thread_return_data;
thread_data * Q;
Q = (thread_data *) threadarg;
cout << Q->number << endl;
R->S = 16; //random number
R->R.push_back("14fjnv"); //random string
R->R.push_back("28jfhn"); //random string
pthread_exit(R);
return 0;
}
int main() {
thread_data A(4444); //initialize with random int
thread_return_data *B; //is pointer
pthread_t aThread; //is variable
pthread_create(&aThread, NULL, Thread, (void *)&A);
pthread_join(aThread, (void **)&B);
cout << B->S << endl;
cout << B->R[0] << endl;
cout << B->R[1] << endl;
cout << A.strings[0];
delete B;
return 0;
}