我想使用pthread_create函数将ofstream对象传递给线程。 假设我在main(int argc,char * argv [])函数中创建了一个这样的对象。
label
并且function1定义为。
imageview
如何通过文件对象访问在主函数中创建的“ file1.txt”?
答案 0 :(得分:0)
有几种方法可以传递对象。一种方法是将其全局化,然后function1()
对其进行访问非常简单。或者,您可以将指向它的指针作为线程的参数传递。在void*
调用中将其强制转换为pthread_create()
,并在线程函数中强制返回。
void* function1(void *input) {
ofstream* file = static_cast<ofstream*>(input);
*file << "Hello" << endl;
return NULL;
}
ofstream file1("./file1.txt", fstream::out|fstream::app);
pthread_t tid;
pthread_create(&tid, NULL, function1, static_cast<void*>(&file1));
请注意,此模式经常导致一个常见错误!当ofstream的作用域在称为pthread_create()
的线程中结束创建时,它将被销毁。如果运行function1()
的线程仍在运行,则可以使用指向现在已销毁的流的指针。
您需要确保ofstream保持活动状态,直到完成另一个线程为止。一种方法是为它提供静态存储持续时间,作为静态局部变量或全局变量。另一个将用new
分配它,然后在使用它的线程中delete
分配它。或者,您可以确保创建的线程在ifstream离开作用域之前已加入。
使用new
和delete
:
void start(void) {
ofstream* file1 = new ofstream("file1.txt", fstream::app);
pthread_create(&tid, NULL, function1, static_cast<void*>(file1));
file1 = NULL; // function1 owns this now, shouldn't be used here anymore
}
void* function1(void* arg) {
ofstream* file1 = static_cast<ofstream*>(arg);
delete file1;
}
在ofstream离开作用域之前加入:
void start(void) {
{
ofstream file1("file1.txt", fstream::app);
pthread_create(&tid, NULL, function1, static_cast<void*>(file1));
// stuff
pthread_join(tid);
// now it's safe for file1 to be destructed.
}
}
还要注意,线程函数应该返回void*
,而不是void
。另外,应将其声明为extern "C"
,以便在C pthreads库调用它时具有正确的ABI。请注意,在新建/删除示例中,如何在启动线程后将指针设置为NULL
。这是因为您不能认为一次可以从多个线程访问ofstream
是安全的。通过将其设置为NULL
,只有function1
线程将能够访问它。
还考虑一下,将名称传递给线程并打开文件可能更有意义?这样可以解决对象的生存期与使用该对象的线程的生存期有关的问题。