- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,让我为代码“示例”的长度表示歉意,我试图提供尽可能小的可执行示例。
我应该提到,队列的形式为:
当调用 run 时,第一个元素被成功地从队列中删除,然后由全局指针 Curr_Thread
引用。我前后检查了队列的形式,一切都在它应该在的地方。
Swapcontext 工作并且控制权传递给 func_1()
,但这就是问题所在。一旦进入 func_1(),队列就会以某种方式被破坏,这意味着头指针仍然指向“虚拟”元素,就像切换之前一样(下一个和上一个指针指向哪里)他们应该),但虚拟元素之后的所有内容现在都指向一些带有随机下一个和上一个指针地址的垃圾元素。当 func_1
调用 yield()
时,内部对 AddTcb()
的调用会崩溃,因为它永远找不到要添加的队列末尾Curr_Thread
。
从 swapcontext
进入 func_1()
之前:
从 swapcontext
进入 func_1()
后立即
为什么调用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/
我正在尝试使用 swapcontext() 创建一个简单的 hello world 示例 这是代码片段: #include #include #include static ucontext_t
首先,让我为代码“示例”的长度表示歉意,我试图提供尽可能小的可执行示例。 我应该提到,队列的形式为: 当调用 run 时,第一个元素被成功地从队列中删除,然后由全局指针 Curr_Thread 引用。
基本上,我正在尝试做的是在具有上下文切换的单个线程上模拟多线程。我每 10 微秒设置一个警报,然后将上下文从一个线程切换到另一个线程。问题是大约五分之一的运行在警报完成 swapcontext 后立即
我正在构建一个抢占式用户空间线程调度程序,它使用计时器来中断线程并根据优先级在线程之间切换。然而,一旦一个线程被中断,我似乎就不能让它完成;只能重新开始。我所要求的甚至可以使用 swapcontext
我正在做一个进行 unix 系统调用的项目。具体而言,我的项目严重依赖对 getcontext()、makecontext()、swapcontext() 和 setcontext() 的调用。我尝试
我对上下文切换很感兴趣。我已将示例代码复制到文件中 http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html
我刚刚将我的项目上传到github: https://github.com/gitlwh/whyisthis/tree/master 您可以克隆它并在 Mac 上运行。这很方便。当我在根文件夹中运行
在 unix 环境中,makecontext()/swapcontext() 函数系列有时用于在 C 中实现协程。然而,这些函数直接操作堆栈和执行流。当从 C 切换到 C++ 时,这些低级功能通常有很
int swapcontext(ucontext_t *oucp, ucontext_t *ucp); int getcontext(ucontext_t *ucp); int setcontext(
我已成功使用 makecontext/swapcontext 移动堆栈。但是,当我尝试将它与 pthread_mutex_lock 或 pthread_mutex_unlock 一起使用时,我总是
我正在使用通常的 makecontext/swapcontext 例程,用 C 语言编写一个小型的概念验证 Fiber 库,但这给我带来了一些麻烦(我的平台是 OSX 10.9 Mavericks,使
我们需要实现一个线程库。但我真的无法解决这个 yield() 函数......所以在 yield() 中,我们需要将当前线程推到就绪线程队列的末尾,并将第一个线程弹出并执行它。(FIFO)我使用的是
我是一名优秀的程序员,十分优秀!