Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 多线程-RunQ随机更改_C_Linux_Multithreading - Fatal编程技术网

C 多线程-RunQ随机更改

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

我的程序启动线程并运行它们。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*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
}