C 多线程-RunQ随机更改
我的程序启动线程并运行它们。RunQ应该是存储线程上下文的TCB_t块的队列(structq)。问题是RunQ在我遍历函数时会随机变化,我不知道为什么。 主要内容: q、 h:C 多线程-RunQ随机更改,c,linux,multithreading,C,Linux,Multithreading,我的程序启动线程并运行它们。RunQ应该是存储线程上下文的TCB_t块的队列(structq)。问题是RunQ在我遍历函数时会随机变化,我不知道为什么。 主要内容: q、 h: #包括 #包括 #包括“TCB.h” #定义GNU源 结构Q{ 结构TCB_t*头; 结构TCB_t*tail; }; void InitQueue(结构Q*Q,结构TCB\u t*head){ q->头部=头部; q->tail=q->head; }; void AddQueue(结构Q*Q,结构TCB\u t*it
#包括
#包括
#包括“TCB.h”
#定义GNU源
结构Q{
结构TCB_t*头;
结构TCB_t*tail;
};
void InitQueue(结构Q*Q,结构TCB\u t*head){
q->头部=头部;
q->tail=q->head;
};
void AddQueue(结构Q*Q,结构TCB\u t*item){
如果(q->head==NULL){
q->head=项目;
q->tail=项目;
}否则如果(q->tail==q->head){
物料->上一个=q->表头;
物料->下一步=q->表头;
q->tail=项目;
q->head->prev=q->tail;
q->head->next=q->tail;
}否则{
物料->上=下->尾;
物料->下一步=q->表头;
q->tail->next=物料;
q->head->prev=物料;
q->tail=项目;
}
}
结构TCB_t*DelQueue(结构Q*Q){
如果(q->head==NULL){
返回NULL;
}
否则如果(q->head==q->tail){
结构TCB_t*temp=q->head;
q->head=NULL;
q->tail=NULL;
返回温度;
}
否则{
结构TCB_t*temp=q->head;
q->tail->next=q->head->next;
q->head=q->head->next;
q->head->prev=q->tail;
返回温度;
}
};
void RotateQ(结构Q*Q){
q->tail=q->head;
q->head=q->head->next;
}
TCB.h:
#include <ucontext.h>
#include <string.h>
typedef struct TCB_t {
struct TCB_t *next;
struct TCB_t *prev;
ucontext_t context;
int thread_id;
} TCB_t;
int global_thread_id = 0;
void init_TCB (TCB_t *tcb, void (*function) (void), void *stackP, int stack_size)
{
memset(tcb, '\0', sizeof(TCB_t)); // wash, rinse
getcontext(&tcb->context); // have to get parent context, else snow forms on hell
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
}
#包括
#包括
类型定义结构TCB_t{
结构TCB_t*next;
结构TCB_t*prev;
ucontext\u t context;
int-thread_-id;
}TCB_t;
int-global_-thread_-id=0;
void init_TCB(TCB_t*TCB,void(*函数)(void),void*stackP,int stack_size)
{
memset(tcb,'\0',sizeof(tcb_t));//清洗、漂洗
getcontext(&tcb->context);//必须获取父上下文,否则雪将在地狱中形成
tcb->context.uc_stack.ss_sp=stackP;
tcb->context.uc\u stack.ss\u size=(size\u t)stack\u size;
tcb->thread\u id=++global\u thread\u id;
makecontext(&tcb->上下文,函数,0);//上下文现在已完成
}
<代码>您确实想要这个标记的C++吗?看起来更像C,使用C标记可能会得到更好的响应。不过,不要编辑以同时使用两者。它们是不同的语言。@ USER481301谢谢,你是正确的。你确定要这个标记C++吗?看起来更像C,使用C标记可能会得到更好的响应。不过,不要编辑以同时使用两者。它们是不同的语言。@user4581301谢谢,你说得对。
#include "q.h"
struct Q* RunQ;
struct TCB_t* Curr_Thread;
struct TCB_t* Prev_Thread;
void start_thread(void (*function) (void)){
int* stack = malloc(8192); //allocate a stack of 8192 bytes
TCB_t* TCB = (TCB_t*)malloc(sizeof(TCB_t)); //allocate a TCB
init_TCB(TCB, function, stack, sizeof(stack)); //call init_TCB
if(global_thread_id == 1){
RunQ = (struct Q*) malloc(sizeof(struct Q));
InitQueue(RunQ, TCB);
}
AddQueue(RunQ, TCB); //call addQ to add this TCB into the "RunQ"
}
void run(){ // real code
Curr_Thread = RunQ->head;
ucontext_t parent; // get a place to store the main context, for faking
getcontext(&parent); // magic sauce
swapcontext(&parent, &(Curr_Thread->context)); // start the first thread
}
void yield(){
Prev_Thread = RunQ->head;
RotateQ(RunQ);
Curr_Thread = RunQ->head;
swapcontext(&(Prev_Thread->context), &(Curr_Thread->context)); //swap the context, from Prev_Thread to the thread pointed to by Curr_Thread
}
#include <unistd.h>
#include <stdlib.h>
#include "TCB.h"
#define _GNU_SOURCE
struct Q {
struct TCB_t* head;
struct TCB_t* tail;
};
void InitQueue(struct Q* q,struct TCB_t* head){
q->head = head;
q->tail = q->head;
};
void AddQueue(struct Q* q, struct TCB_t* item){
if(q->head == NULL) {
q-> head = item;
q-> tail = item;
} else if(q->tail == q->head) {
item->prev = q->head;
item->next = q->head;
q->tail = item;
q->head->prev = q->tail;
q->head->next = q->tail;
} else {
item->prev = q->tail;
item->next = q->head;
q->tail->next = item;
q->head->prev = item;
q->tail = item;
}
}
struct TCB_t* DelQueue(struct Q* q){
if(q->head == NULL) {
return NULL;
}
else if(q->head == q->tail) {
struct TCB_t* temp = q->head;
q->head = NULL;
q->tail = NULL;
return temp;
}
else {
struct TCB_t* temp = q->head;
q->tail->next = q->head->next;
q->head = q->head->next;
q->head->prev = q->tail;
return temp;
}
};
void RotateQ(struct Q* q){
q->tail = q->head;
q->head = q->head->next;
}
#include <ucontext.h>
#include <string.h>
typedef struct TCB_t {
struct TCB_t *next;
struct TCB_t *prev;
ucontext_t context;
int thread_id;
} TCB_t;
int global_thread_id = 0;
void init_TCB (TCB_t *tcb, void (*function) (void), void *stackP, int stack_size)
{
memset(tcb, '\0', sizeof(TCB_t)); // wash, rinse
getcontext(&tcb->context); // have to get parent context, else snow forms on hell
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
}