@MuffinLover

Не могу понять почему не работает USER тред?

КОД
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include <signal.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sched.h>

#define MAX_THREADS 4
#define STACK_SIZE 8192

typedef struct {
    ucontext_t context;
    int active;
    void (*func)(void);
} Thread;

Thread threads[MAX_THREADS];
int current_thread = 0;

void schedule() {
    int next_thread = (current_thread + 1) % MAX_THREADS;
    int original_thread = current_thread;
    do {
        if (threads[next_thread].active) {
            current_thread = next_thread;
            break;
        }
        next_thread = (next_thread + 1) % MAX_THREADS;
    } while (next_thread != original_thread);
}

void thread_func1() {
    printf("Thread 1 is running...\n");
    threads[current_thread].active = 0;
}

void thread_func2() {
    printf("Thread 2 is running...\n");
    threads[current_thread].active = 0;
}

void monitor_thread(void* arg) {
    while (1) {
        if (!threads[current_thread].active) {
            schedule();
            threads[current_thread].func();
        }
    }
}

int create_thread(void (*func)(void)) {
    int thread_id = -1;
    for (int i = 0; i < MAX_THREADS; i++) {
        if (!threads[i].active) {
            thread_id = i;
            break;
        }
    }
    if (thread_id == -1) {
        return -1;
    }

    getcontext(&threads[thread_id].context);
    threads[thread_id].context.uc_stack.ss_sp = malloc(STACK_SIZE);
    threads[thread_id].context.uc_stack.ss_size = STACK_SIZE;
    makecontext(&threads[thread_id].context, (void (*)())func, 0);
    threads[thread_id].func = func;
    threads[thread_id].active = 1;
    return thread_id;
}

int main() {
    create_thread(thread_func1);
    create_thread(thread_func2);
    int pid = clone((int (*)(void *))monitor_thread, malloc(STACK_SIZE) + STACK_SIZE, CLONE_VM | CLONE_THREAD, NULL);
    setcontext(&threads[current_thread].context);
    return 0;
}


пытаюсь в отладке понять почему thread_func2 не исполняется, но ничего понять не могу, подскажите, пожалуйста
  • Вопрос задан
  • 81 просмотр
Пригласить эксперта
Ответы на вопрос 2
@res2001
Developer, ex-admin
Видимо потому что main заканчивается и программа завершается вместе со всеми потоками.

Вообще не понятно, что ты этим хотел сказать. Где вызов swapcontext? Без него стеки псевдопотоков не используются и переключение контекстов не происходит. Зачем они тогда тут нужны?
В прошлом варианте с таймером, по крайней мере, была идея и было понятно, чего ты хотел добиться. Хоть оно и не работало.
Ответ написан
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
почему не работает USER тред?

Потому что, опять, ты вызываешь makecontext не задав uc_link. thread_func1 отрабатывает, а дальше гонка между вызовом thread_func2 из monitor_thread и завершением программы из-за возврата из функции контекста в контексте созданном с uc_link == NULL.

Но и без этого код выглядит загадочно. Непонятно зачем мешать в одну кучу контексты и clone. Непонятно зачем дублировать указатель на функцию в Thread::func и в Thread::context. Непонятно зачем контексты, если schedule их не использует. Непонятно, зачем monitor_thread занимается активным ожиданием Thread::active. Непонятно, зачем функции потоков лезут в потроха Thread. Короче, этому коду не хватает идеи.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы