Ich habe eine Struktur namens thread
mit einem Mitglied namens ucontext* tctx
definiert.Seg-Fehler beim Versuch, swapcontext() in ein Strukturelement, das in einer Warteschlange gespeichert ist,
In einer Funktion namens create_thread()
, ich ein Thread-Objekt auf dem Heap erstellen und definieren jedes seiner Mitglieder (einschließlich der Mitglieder des Ucontext-Objekts). Ich füge dann den Zeiger zu diesem Thread-Objekt in einen Queue-Container.
Wenn ich die Warteschlange in einen Thread-Kontext wechseln, segne ich Fehler. Ich bin nicht sicher, warum das passiert. Hier
ist der vollständige Code:
#include <iostream>
#include <queue>
#include <ucontext.h>
#define STACK_SIZE 262144
using namespace std;
typedef struct thread
{
int thread_id;
ucontext* tctx;
char* sp;
}thread;
int thread_id;
ucontext_t* ctx1; //Unused, currently
ucontext_t* cur;
queue<thread*> ready_queue;
/* Function Declaration */
thread* create_thread(int,int);
void foo1(int);
int main(int argc, char** argv)
{
cout << " PROGRAM START ***** \n";
/* Create 'i' number of threads */
for(int i = 0; i < 2; i++)
{
cout << "\nready_queue size before creating thread = " << ready_queue.size() << endl;
cout << "Calling create thread ... id=" << i << endl;
create_thread(i, i*1000);
cout << "ready_queue size after creating thread = " << ready_queue.size() << endl;
}
cout << " \t>> THREADS CREATED \n";
cout << " \t>> SWITCHING CONTEXT \n";
/* Save current context to cur, swap context to first thread in queue */
swapcontext(cur, ready_queue.front()->tctx); //Seg fault!
cout << " PROGRAM TERMI ***** \n";
return 0;
}
thread* create_thread(int id, int arg)
{
static int num_threads = 0;
/* Create a new thread struct, ucontxt for the thread, and put in ready queue */
thread* n = new thread;
getcontext(n->tctx);
n -> thread_id = id;
n -> tctx = new ucontext_t;
n -> sp = new char[STACK_SIZE];
n->tctx->uc_stack.ss_sp = n->sp;
n->tctx->uc_stack.ss_size = STACK_SIZE;
n->tctx->uc_stack.ss_flags = 0;
n->tctx->uc_link = NULL;
makecontext(n->tctx, (void(*)()) foo1, 1, arg); //Thread shall call foo() with argument 'arg'
/* Push new thread into ready_queue */
ready_queue.push(n);
num_threads++;
cout << "Thread #" << num_threads << " was created. Thread.ID[" << id << "]\n";
return n;
}
//Application function
void foo1(int arg)
{
cout << "Calling from foo1(). I have " << arg << "!\n";
}
Edited:
Ich habe bemerkt, dass, wenn ich getcontext(n->tctx);
nach n -> tctx = new ucontext_t;
rufen das Problem behoben ist. Es scheint, dass das Problem sein könnte, dass getcontext
versuchte, etwas in dem Heap zu initialisieren, der noch nicht zugewiesen worden war.
Warum ist es besser, ein ucontext_t-Objekt erstellen? Was ist, wenn ich es im freien Speicher (dem Heap) erstellen möchte? – MTV
Die Thread-Struktur selbst wird auf dem Heap erstellt, so dass sich eine ucontext_t-Membervariable ebenfalls auf dem Heap befinden würde. Eine globale Variable ist auch nicht auf dem Stapel zugeordnet. – Elijan9