标签: ucontext

getcontext系统调用了什么(ucontext.h)呢?

我去年使用了操作系统,在此期间我使用用户上下文(在标题中定义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)

c operating-system posix ucontext

10
推荐指数
1
解决办法
3123
查看次数

valgrind错误和ucontext.为什么"使用8英寸的未初始化值"?

我一直试图理解为什么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)

c linux valgrind ucontext

8
推荐指数
1
解决办法
1629
查看次数

使用带有SIG_INFO的sigaction处理程序的第三个参数(void*context)会导致分段错误

我已经减少了一个巨大的光纤调度程序代码,该代码产生了以下几行的问题.
我期望的是每次都清理地返回上下文,传递给处理程序.
我得到的是"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(&currently_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.

c gcc signals handler ucontext

7
推荐指数
1
解决办法
4510
查看次数

使用getcontext/setcontext切换堆栈

我试图了解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)

c ucontext

6
推荐指数
1
解决办法
1822
查看次数

是不是在linux上定义了`stack_t`类型?

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 linux ucontext

4
推荐指数
1
解决办法
2546
查看次数

上下文切换 - ucontext_t和makecontext()

我正在研究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)

c context-switch ucontext

4
推荐指数
1
解决办法
1万
查看次数

为什么 ucontext 有这么高的开销?

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)

[关联]

我相信这些实验的源代码托管在 GitHub 上

我的问题是,为什么ucontext的开销比 Boost 库的实现高 20 …

c c++ boost ucontext

4
推荐指数
1
解决办法
1267
查看次数

使用 ucontext 和信号的 mac OSX 上的用户线程调度 API

我正在设计一个具有以下功能的调度算法:

  • 在一个进程中有 2 个用户线程(上下文)(我应该做 3 个线程,但这在 osx 上还不起作用,所以我决定现在让 2 个工作)
  • 使用每 1 秒关闭一次的 SIGALRM 信号进行抢占,并将控制从一个上下文更改为另一个上下文,并保存在执行切换之前正在运行的上下文的当前状态(寄存器和当前位置)。

我注意到的是以下内容:

  • ucontext.h 库在 mac osx 上的行为很奇怪,而当它在 Linux 中应用时,它的行为完全符合预期(此 man 链接中的示例:http : //man7.org/linux/man-pages/man3/makecontext .3.html在 linux 上完美运行,而在 mac 上,它在进行任何交换之前因分段错误而失败)。不幸的是,我必须让它在 osx 上运行,而不是在 linux 上运行。
  • 我设法通过使用 getcontext() 然后 setcontext() 进行上下文交换来解决 osx 上的 swapcontext 错误。
  • 在我的信号处理函数中,我使用 sa_sigaction( int sig, siginfo_t *s, void * cntxt ) 因为第三个变量曾经将它重新转换为 ucontext_t 指针是关于被中断的上下文的信息(这在 Linux 上是正确的)一旦我测试了它)但在 mac 上它没有指向正确的位置,因为当我使用它时我再次遇到分段错误。

我为每个上下文设计了我的测试函数,使其在 while 循环内循环,因为我想中断它们并确保它们返回到该函数内的适当位置执行。我已经定义了一个静态全局计数变量,它可以帮助我查看我是否在正确的用户线程中。

最后一个注意事项是,我发现在我的 while 循环中调用 getcontext() 并在测试函数中不断更新我当前上下文的位置,因为它是空的 while 循环,因此在该上下文的时间到来时调用 setcontext() 使得它从适当的地方执行。此解决方案是多余的,因为这些功能将从 API 外部提供。

    #include <stdio.h> …
Run Code Online (Sandbox Code Playgroud)

c scheduler user-thread ucontext osx-yosemite

4
推荐指数
1
解决办法
1245
查看次数

Linux上下文切换内部:当进程在计时器中断之前退出时会发生什么?

当计时器中断之前进程退出时,如何在Linux内核中进行上下文切换?

我知道,如果进程正在运行并且发生计时器中断,那么schedule如果设置了该标志,则会自动调用该函数,然后调度函数会选择下一个要运行的进程。基本上,在这种情况下,计划功能在当前进程的上下文中运行,但是,即使在定时器中断之前进程退出,也会发生什么情况?schedule在这种情况下谁调用函数?在什么情况下运行?

linux scheduler ucontext

4
推荐指数
1
解决办法
437
查看次数

在Linux中的Ucontext

我读到ucontext用于在linux中的多个线程之间保存上下文.由于操作系统在不同线程之间进行上下文切换,为什么linux提供此头文件(ucontext.h)进行上下文切换?

c linux ucontext

3
推荐指数
1
解决办法
7074
查看次数

为什么srand(time(NULL))在main上给我分段错误?

这里需要一些帮助.

我想了解这段代码中发生了什么.

我正在尝试为函数内部创建ticketsTCP_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)

c random time srand ucontext

2
推荐指数
1
解决办法
905
查看次数

上下文切换 - makecontext和swapcontext在这里工作(OSX)

我对上下文切换很开心.我已将示例代码复制到文件 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 …

c macos context-switch ucontext

2
推荐指数
1
解决办法
1099
查看次数