gpt4 book ai didi

c - 调用 swapcontext() 后队列丢失指针

转载 作者:行者123 更新时间:2023-11-30 15:05:17 26 4
gpt4 key购买 nike

首先,让我为代码“示例”的长度表示歉意,我试图提供尽可能小的可执行示例。

我应该提到,队列的形式为:

circular queue

当调用 run 时,第一个元素被成功地从队列中删除,然后由全局指针 Curr_Thread 引用。我前后检查了队列的形式,一切都在它应该在的地方。

Swapcontext 工作并且控制权传递给 func_1(),但这就是问题所在。一旦进入 func_1(),队列就会以某种方式被破坏,这意味着头指针仍然指向“虚拟”元素,就像切换之前一样(下一个和上一个指针指向哪里)他们应该),但虚拟元素之后的所有内容现在都指向一些带有随机下一个和上一个指针地址的垃圾元素。当 func_1 调用 yield() 时,内部对 AddTcb() 的调用会崩溃,因为它永远找不到要添加的队列末尾Curr_Thread

swapcontext 进入 func_1() 之前:

pointer pointing where they should

swapcontext 进入 func_1() 后立即

pointers to nowhere

为什么调用swapcontext后我的队列结构突然改变了?为什么它在没有其他交互的情况下发生变化?

谢谢。

#include <ucontext.h>
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#include <stdlib.h>

#define MAX_QUEUE 100
TCB_t *ReadyQ;
TCB_t *Curr_Thread;
int global_thread_id = 0;

typedef struct TCB_t {
struct TCB_t *next;
struct TCB_t *prev;
ucontext_t context;
int thread_id;
} TCB_t;

void start_thread(void (*function) (void));
void run();
void yield();
void print_id(TCB_t *tcb);
void func_1();
void (*f1)();
TCB_t* newItem();
TCB_t* newTcb(TCB_t* head);
void AddTcb(TCB_t* head_node, TCB_t* new_node);
TCB_t* DelTcb(TCB_t* head);

void init_TCB (TCB_t *tcb, void *function, void *stackP, int stack_size)
{
memset(tcb, '\0', sizeof(TCB_t));
getcontext(&tcb->context);
tcb->context.uc_stack.ss_sp = stackP;
tcb->context.uc_stack.ss_size = (size_t) stack_size;
tcb->thread_id = global_thread_id ++;
makecontext(&tcb->context, function, 0);// context is now cooked
}

void start_thread(void (*function) (void)){
void *stack; //generic stack pointer
TCB_t *new_tcb; //new TCB

stack = malloc(STACK_SIZE);
new_tcb = (TCB_t*) malloc(sizeof(TCB_t));

init_TCB(new_tcb, function, stack, sizeof(stack));

AddTcb(ReadyQ, new_tcb);
}

void run(){
Curr_Thread = DelTcb(ReadyQ);
ucontext_t parent;
getcontext(&parent); //get the current running context
swapcontext(&parent, &(Curr_Thread->context)); //switch it to the next q element
}

void yield(){
TCB_t *prev_thread;

AddTcb(ReadyQ, Curr_Thread);
prev_thread = Curr_Thread;
Curr_Thread = DelTcb(ReadyQ);
//swap the context from the previous thread to the thread pointed to by Curr_Thread
swapcontext(&(prev_thread->context), &(Curr_Thread->context));
}

struct TCB_t* newItem(){
TCB_t* new_tcb; //create new node on heap
new_tcb = (TCB_t*) malloc(sizeof(TCB_t));
return new_tcb; //return the new node
}

TCB_t* newQueue(){
TCB_t *dummy = newItem(); //create dummy node
TCB_t *head = newItem();

dummy->next = NULL; //set dummy elements to NULL
dummy->prev = NULL;

head->next = dummy; //point head at dummy
head->prev = NULL;

return head; //return head
}
//Add new item to queue
void AddTcb(TCB_t* head_tcb_node, TCB_t* new_tcb_node){
TCB_t* tmp, *dummy;
dummy = head_tcb_node->next; //tmp is header node
if(dummy->next == NULL){
dummy->next = new_tcb_node;
dummy->prev = new_tcb_node;
new_tcb_node->next = dummy;
new_tcb_node->prev = dummy;
}else{
tmp = dummy->next;
while(tmp->next != dummy){
tmp = tmp->next;
}
new_tcb_node->next = tmp->next;
new_tcb_node->prev = tmp;
tmp->next = new_tcb_node;
dummy->prev = new_tcb_node;
}
}
//Remove and return first queue element
TCB_t* DelTcb(TCB_t *head){
TCB_t *dummy, *pop, *tmp;
dummy = head->next;

if (dummy->next == NULL){
pop = NULL;
}else{
pop = dummy->next;
if(pop->next == dummy){
dummy->next = NULL;
dummy->prev = NULL;
}else{
tmp = pop->next;
tmp->prev = dummy;
dummy->next = tmp;
}
pop->next = pop->prev = NULL;
}
return pop;
}
void func_1(){
int local_1 = 0;
while(1){
//print_id(ReadyQ);
printf("\n");
printf("Global int: %d\t", gbl_num);
printf("Local int, function 1: %d\n\n", local_1);
gbl_num++;
local_1++;
yield();
sleep(1);
}
}
int main(){
ReadyQ = newQueue();

f1 = func_1;
start_thread(f1);
run();

return 0;
}

最佳答案

我也有类似的问题。我像下面一样直接分配了值,它对我有用。

tcb->context.uc_stack.ss_sp = malloc(8192);
tcb->context.uc_stack.ss_size = 8192;

关于c - 调用 swapcontext() 后队列丢失指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39939606/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com