Dalam C, konteks ialah keadaan pelaksanaan semasa program, termasuk daftar (kawasan storan kecil dalam CPU, digunakan untuk menyimpan data dan arahan semasa pelaksanaan program), pembolehubah dan aliran arahan, penting untuk menukar tugas.
Fungsi utama adalah untuk membolehkan multitasking. Ini memastikan sistem boleh bertukar antara proses dengan cekap.
Fail contexts.c telah disediakan di sini. Ia adalah demonstrasi cara konteks berfungsi.
Tepat di bahagian atas fail ini, kami melihat import pustaka ucontext.h. Ia membolehkan anda memanipulasi konteks pelaksanaan.
Dalam petikan di bawah kita melihat bahawa 3 konteks dicipta dan 3 konteks ini akan mempunyai memori yang diperuntukkan saiz STACKSIZE.
#define STACKSIZE 64 * 1024 /* tamanho de pilha das threads */ ucontext_t ContextPing, ContextPong, ContextMain;
Dan tidak lama kemudian, fungsi Ping dan Pong yang akan dilaksanakan dalam konteks masing-masing:
void BodyPing(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; i < 4; i++) { printf("%s: %d\n", (char *)arg, i); swapcontext(&ContextPing, &ContextPong); } printf("%s: fim\n", (char *)arg); swapcontext(&ContextPing, &ContextMain); } /*****************************************************/ void BodyPong(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; i < 4; i++) { printf("%s: %d\n", (char *)arg, i); swapcontext(&ContextPong, &ContextPing); } printf("%s: fim\n", (char *)arg); swapcontext(&ContextPong, &ContextMain); } /*****************************************************/
Dalam fungsi utama, malloc digunakan untuk menempah tindanan, di mana ia kemudiannya ditetapkan dengan uc_stack.ss_sp kepada konteks dan swapcontext digunakan untuk bertukar antaranya.
int main(int argc, char *argv[]) { char *stack; printf("main: inicio\n"); getcontext(&ContextPing); stack = malloc(STACKSIZE); if (stack) { ContextPing.uc_stack.ss_sp = stack; ContextPing.uc_stack.ss_size = STACKSIZE; ContextPing.uc_stack.ss_flags = 0; ContextPing.uc_link = 0; } else { perror("Erro na criação da pilha: "); exit(1); } makecontext(&ContextPing, (void *)(*BodyPing), 1, " Ping"); getcontext(&ContextPong); stack = malloc(STACKSIZE); if (stack) { ContextPong.uc_stack.ss_sp = stack; ContextPong.uc_stack.ss_size = STACKSIZE; ContextPong.uc_stack.ss_flags = 0; ContextPong.uc_link = 0; } else { perror("Erro na criação da pilha: "); exit(1); } makecontext(&ContextPong, (void *)(*BodyPong), 1, " Pong"); swapcontext(&ContextMain, &ContextPing); swapcontext(&ContextMain, &ContextPong); printf("main: fim\n"); exit(0); }
Keluaran program yang dilaksanakan:
main: inicio Ping: inicio Ping: 0 Pong: inicio Pong: 0 Ping: 1 Pong: 1 Ping: 2 Pong: 2 Ping: 3 Pong: 3 Ping: fim Pong: fim main: fim
Dengan ini, kita dapat melihat bahawa walaupun mengubah konteks, nilai yang "mengalir" melalui fungsi dikekalkan, contoh dalam kes ini ialah indeks untuk.
Anda mungkin perasan bahawa terdapat malloc untuk konteks Ping dan Pong, tetapi kami melihat bahawa terdapat konteks untuk main juga, mengapa tidak ada malloc untuknya?
ContextMain tidak memerlukan tindanan berasingan kerana ia beroperasi pada tindanan utas utama, manakala konteks Ping dan Pong mempunyai tindanan sendiri yang diperuntukkan secara dinamik.
Jika saya mencipta konteks dan tidak memperuntukkan memori untuknya, apabila kita menggunakan swap, ia pergi ke tindanan utama program.
Kod ini daripada Profesor Maziero, ditemui dalam sub-projek PingPongOS yang dibangunkan "Trocas de Contexto".
Atas ialah kandungan terperinci Dia e - Memahami konteks dalam C. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!