【发布时间】:2015-09-13 15:02:22
【问题描述】:
我正在尝试将 QEMU 的用户模式模拟器作为我正在编写的更大程序中的线程运行。我已经修改了linux-user/main.c 文件,因此标准的int main(int argc, char **argv, char **envp 函数现在称为void *qemu_user_mode_func(void *arg)。我还在该函数的末尾添加了pthread_exit(NULL),这是 pthreads 的标准做法(或者我被告知)。
但是,当我尝试运行包含我自己的测试函数的第二个线程时(如下图 void *test_func(void *arg) 所示),进程在第二个线程完成之前退出,即使调用了 pthread_join(@987654328 @),我读过它会阻塞调用线程,直到线程 tid 返回。 QEMU 的用户模式仿真是否以阻止pthread_join 退出的方式退出,或者我只是使用了错误的线程?
这是我的代码(不包括大部分qemu_user_mode_func):
void *qemu_user_mode_func(void *arg)
{
thread_data_t *thread_data;
int argc;
char **argv;
char **envp;
/** QEMU's normal code **/
//return 0;
pthread_exit(NULL);
}
void *test_func(void *arg) {
struct timespec time;
time.tv_sec = 7;
time.tv_nsec = 0;
nanosleep(&time, NULL);
printf("hello, world - from a thread\n");
pthread_exit(NULL);
}
int main(int argc, char**argv, char **envp) {
//Initialize variables to create thread
int rc;
pthread_t threads[2];
thread_data_t main_args;
main_args.tid = 1;
main_args.argc = argc;
main_args.argv = argv;
main_args.envp = envp;
//Create thread
if ((rc = pthread_create(&(threads[0]), NULL, test_func, NULL))) {
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
if ((rc = pthread_create(&(threads[1]), NULL, qemu_user_mode_func, (void *)&main_args))) {
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
//Wait for thread to finish, then terminate process
for (rc = 0; rc < 2; rc++) {
pthread_join(threads[rc], NULL);
}
return 0;
}
编辑:我在void cpu_loop(CPUX86State *env) 函数中发现,当模拟程序结束时,QEMU 调用系统调用 231,即sys_exit_group(根据1)。所以我猜这个系统调用正在终止我正在运行的整个过程。我会很感激任何关于如何解决这个问题的提示!
【问题讨论】:
-
你为什么不直接
fork()并在fork child 中调用qemu main 函数? -
@caf - 这与我使用 qemu 的方式有关 - 主要是,我正在使用其中的动态二进制翻译系统,称为 Tiny Code Generator。我试图在程序执行的中途开始 DBT - 例如,程序在本机硬件上启动并在执行的中途迁移到虚拟机。由于二进制文件的 text + data 部分在线程之间共享,因此对这些部分的任何内存引用在两个线程中都是有效的;所有改变的是堆栈(这是一个完全不同的野兽)。我同意
fork通常是更好的解决方案!
标签: c multithreading pthreads qemu system-calls