我去年使用了操作系统,在此期间我使用用户上下文(在标题中定义ucontext.h)来实现项目的线程调度程序(其中每个线程模拟一个进程).我正在参加一个讲座,并将谈论用户上下文,我刚刚想到,尽管去年完成了这个项目,但我并不真正理解getcontext系统调用究竟是做什么的.
该getcontext状态的手册页"将ucp指向的结构初始化为当前活动的上下文".对于参数setcontext,它还指出"如果ucp参数是用getcontext()创建的,程序执行就会继续,好像刚刚返回了相应的getcontext()调用一样." 好的,我明白了.
所以这就是我所困惑的.通常,对于我学习它的方式,要执行上下文切换,可以初始化ucontext_t结构并交换/设置它:
ucontext_t ucp;
ucontext_t oucp;
getcontext(&ucp);
// Initialize the stack_t struct in the ucontext_t struct
ucp.uc_stack.ss_sp = malloc(STACK_SIZE);
ucp.uc_stack.ss_size = STACK_SIZE;
ucp.uc_stack.ss_flags = 0;
ucp.uc_link = /* some other context, or just NULL */;
// Don't block any signals in this context
sigemptyset(&ucp.uc_sigmask);
// Assume that fn is a function that takes 0 arguments and returns void
makecontext(&ucp, fn, 0);
// Perform the context switch. Function 'fn' …Run Code Online (Sandbox Code Playgroud) 我一直试图理解为什么valgrind抱怨使用ucontexts的小型测试程序"使用8号未初始化的值".它基本上是一个创建"n_ucs"ucontexts并在"max_switch"时间内切换它们的程序.
我理解"警告:客户端切换堆栈?" (这基本上就是程序的全部内容),但我对所有"使用未初始化的8号值"都没有意义
我想得到一些帮助,了解Valgrind错误是否为误报,或者该程序是否存在根本错误.(我在一个使用相同机制的更大的程序中看到了很多它们,但是我把它提炼到最低限度以便在这里发布).
任何帮助表示赞赏.
谢谢,
插口
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <ucontext.h>
#define STACK_SIZE (8*1024)
int n_ucs = 1;
int max_switchs = 10;
int n_switchs = 0;
int tid = 0;
ucontext_t *ucs;
static ucontext_t engine_uc;
static void func(int arg)
{
while (n_switchs < max_switchs) {
int c_tid = tid;
int n_tid = (tid + 1) % n_ucs;
n_switchs++;
tid = n_tid;
swapcontext(&ucs[c_tid], &ucs[n_tid]);
}
}
int main(int argc, char **argv)
{
if (argc > 1)
n_ucs …Run Code Online (Sandbox Code Playgroud) 我已经减少了一个巨大的光纤调度程序代码,该代码产生了以下几行的问题.
我期望的是每次都清理地返回上下文,传递给处理程序.
我得到的是"Handler."打印出三次,然后是分段错误.
#include <ucontext.h>
#include <signal.h>
#include <stdio.h>
ucontext_t currently_executed_context;
void handler_sigusr1(int signum, siginfo_t* siginfo, void* context)
{
currently_executed_context = (*(ucontext_t*)context);
printf("Handler. ");
setcontext(¤tly_executed_context);
}
int main()
{
setbuf(stdout,0);
struct sigaction action_handler;
action_handler.sa_sigaction = handler_sigusr1;
action_handler.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1,&action_handler,NULL);
for(;;) { kill(getpid(),SIGUSR1); sleep(1); }
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在两个不同的Linux发行版上使用gcc-4.4.3和gcc-4.4.5.
我试图了解getcontext/setcontext是否能在特定场景中正常工作.
我可以看到如何使用setcontext()将堆栈展开回历史记录中的某个位置.
#include <stdio.h>
#include <ucontext.h>
int rollback = 0;
ucontext_t context;
void func(void)
{
setcontext(cp);
}
int main(void)
{
getcontext(&context);
if (rollback == 0)
{
printf("getcontext has been called\n");
rollback++;
func();
}
else
{
printf("setcontext has been called\n");
}
}
Run Code Online (Sandbox Code Playgroud)
但是我想知道在放松之后你是否可以重新回到未来的某个地方?我想这取决于getcontext()调用捕获堆栈的副本,我无法在文档中找到确切的详细信息.
#include <stdio.h>
#include <ucontext.h>
int rollback = 0;
int backToFuture = 0;
ucontext_t context;
ucontext_t futureContext;
void func(void)
{
// Some complex calc
if (some-condition)
{
getcontext(&futureContext); // After returning I want to come back
// …Run Code Online (Sandbox Code Playgroud) Linux平台是Ubuntu 12.04
我的源代码中包含以下标头:
#include <unistd.h>
#include <signal.h>
#include <ucontext.h>
...
Run Code Online (Sandbox Code Playgroud)
然而,当我编译它时,它会抱怨 /usr/include/x86_64-linux-gnu/sys/ucontext.h:139:5: error: unknown type name 'stack_t'
我用Google搜索并发现stack_t应该定义signal.h,但这里似乎没有定义?
我正在研究C编程中的上下文切换,并在Internet上找到了以下示例代码.我试图弄清楚是否只有makecontext()函数可以触发一个做某事的函数.的其他功能,例如setcontext(),getcontext()和swapcontext()用于设置的上下文.
该makecontext()直到改变致力于其附加的功能和它的参数(一个或多个)的情况下,确实功能棒的背景下所有的时间?
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ucontext.h>
4 #define MEM 64000
5
6 ucontext_t T1, T2, Main;
7 ucontext_t a;
8
9 int fn1()
10 {
11 printf("this is from 1\n");
12 setcontext(&Main);
13 }
14
15 void fn2()
16 {
17 printf("this is from 2\n");
18 setcontext(&a);
19 printf("finished 1\n");
20 }
21
22 void start()
23 {
24 getcontext(&a);
25 a.uc_link=0;
26 a.uc_stack.ss_sp=malloc(MEM);
27 …Run Code Online (Sandbox Code Playgroud) Boost v1.59 中 Boost.Context 的文档报告了以下性能比较结果:
+----------+----------------------+-------------------+-------------------+----------------+
| Platform | ucontext_t | fcontext_t | execution_context | windows fibers |
+----------+----------------------+-------------------+-------------------+----------------+
| i386 | 708 ns / 754 cycles | 37 ns / 37 cycles | ns / cycles | ns / cycles |
| x86_64 | 547 ns / 1433 cycles | 8 ns / 23 cycles | 16 ns / 46 cycles | ns / cycles |
+----------+----------------------+-------------------+-------------------+----------------+
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么ucontext的开销比 Boost 库的实现高 20 …
我正在设计一个具有以下功能的调度算法:
我注意到的是以下内容:
我为每个上下文设计了我的测试函数,使其在 while 循环内循环,因为我想中断它们并确保它们返回到该函数内的适当位置执行。我已经定义了一个静态全局计数变量,它可以帮助我查看我是否在正确的用户线程中。
最后一个注意事项是,我发现在我的 while 循环中调用 getcontext() 并在测试函数中不断更新我当前上下文的位置,因为它是空的 while 循环,因此在该上下文的时间到来时调用 setcontext() 使得它从适当的地方执行。此解决方案是多余的,因为这些功能将从 API 外部提供。
#include <stdio.h> …Run Code Online (Sandbox Code Playgroud) 当计时器中断之前进程退出时,如何在Linux内核中进行上下文切换?
我知道,如果进程正在运行并且发生计时器中断,那么schedule如果设置了该标志,则会自动调用该函数,然后调度函数会选择下一个要运行的进程。基本上,在这种情况下,计划功能在当前进程的上下文中运行,但是,即使在定时器中断之前进程退出,也会发生什么情况?schedule在这种情况下谁调用函数?在什么情况下运行?
我读到ucontext用于在linux中的多个线程之间保存上下文.由于操作系统在不同线程之间进行上下文切换,为什么linux提供此头文件(ucontext.h)进行上下文切换?
这里需要一些帮助.
我想了解这段代码中发生了什么.
我正在尝试为函数内部创建tickets的TCP_t结构生成随机数ccreate.
问题是,每次执行此代码时,srand(time(NULL))它都会反复返回相同的"随机"数字序列,例如:
TID: 0 | TICKET : 103
TID: 1 | TICKET : 198
Run Code Online (Sandbox Code Playgroud)
所以我随着时间的推移将其播种,以生成真正随机的数字.
当我将种子放在newTicket函数内部时,它会在每次执行时带来不同的数字,但每个线程的数字都相同.以下是输出示例:
执行1:
TID: 0 | TICKET : 148
TID: 1 | TICKET : 148
Run Code Online (Sandbox Code Playgroud)
执行2:
TID: 0 | TICKET : 96
TID: 1 | TICKET : 96
Run Code Online (Sandbox Code Playgroud)
因此,经过一些研究,我发现我不应该在每次打电话时播种它,rand而只是在节目开始时播种一次.现在,在将种子放入main函数之后,它给了我分段错误,我没有IDEA为什么.
这可能是一个愚蠢的问题,但我真的想了解发生了什么.
不知怎的,种子搞砸了什么?我错过了什么吗?我应该以另一种方式生成随机数吗?
#include <ucontext.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MAX_TICKET 255
#define STACK_SIZE 32000
typedef struct s_TCB …Run Code Online (Sandbox Code Playgroud) 我对上下文切换很开心.我已将示例代码复制到文件 http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html
我为OSX定义了宏_XOPEN_SOURCE.
#define _XOPEN_SOURCE
#include <stdio.h>
#include <ucontext.h>
static ucontext_t ctx[3];
static void
f1 (void)
{
puts("start f1");
swapcontext(&ctx[1], &ctx[2]);
puts("finish f1");
}
static void
f2 (void)
{
puts("start f2");
swapcontext(&ctx[2], &ctx[1]);
puts("finish f2");
}
int
main (void)
{
char st1[8192];
char st2[8192];
getcontext(&ctx[1]);
ctx[1].uc_stack.ss_sp = st1;
ctx[1].uc_stack.ss_size = sizeof st1;
ctx[1].uc_link = &ctx[0];
makecontext(&ctx[1], f1, 0);
getcontext(&ctx[2]);
ctx[2].uc_stack.ss_sp = st2;
ctx[2].uc_stack.ss_size = sizeof st2;
ctx[2].uc_link = &ctx[1];
makecontext(&ctx[2], f2, 0);
swapcontext(&ctx[0], &ctx[2]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我建造它
gcc -o …