Я пытаюсь запустить эмулятор режима пользователя QEMU в виде потока в более крупной программе, которую я пишу. Я изменил файл linux-user/main.c
, так что теперь стандартная функция int main(int argc, char **argv, char **envp
называется void *qemu_user_mode_func(void *arg)
. Я также добавил pthread_exit(NULL)
в конце этой функции, как это стандартная практика для pthreads (или так мне сказали).Выходит ли эмуляция режима пользователя QEMU таким образом, чтобы предотвратить блокирование pthread_join?
Однако, когда я пытаюсь запустить второй поток, который содержит свою собственную функцию тестирования (как показано ниже в void *test_func(void *arg)
), процесс выходит перед вторым потоком завершается, даже с вызовом pthread_join(
tid
)
, который я ve читает блокирует вызывающую нить до тех пор, пока нить 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;
}
EDIT: Я обнаружил в функции void cpu_loop(CPUX86State *env)
, что когда эмулировать программа достигает свое заключение, QEMU вызывает системный вызов 231, который sys_exit_group
(согласно 1). Поэтому я предполагаю, что этот syscall завершает весь процесс, который я запускаю. Я был бы признателен за любые советы о том, как обойти это!
Почему вы не просто 'вилка()' и называют основной функцией QEMU в раздвоенной ребенка? – caf
@caf - Это связано с тем, как я использую qemu - в основном, я работаю над использованием в нем динамической бинарной системы перевода, известной как генератор крошечного кода. Я пытаюсь начать DBT частично через выполнение программы - как и в, программа запускается на собственном оборудовании и переносится на виртуальную машину частично через выполнение. Поскольку секции text + data двоичного файла разделяются между потоками, любые ссылки на память этих разделов действительны в обоих потоках; все, что меняется, это стек (который является целым другим зверьком). Я согласен, что 'fork' - лучшее решение, как правило,! – tonysdg