使用SIGALRM切换线程上下文 [英] Switching Thread Contexts with SIGALRM

查看:128
本文介绍了使用SIGALRM切换线程上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题.我需要实现一个使用计时器和SIGALRM切换ucontext线程的程序,但是使用evict_thread函数切换线程时遇到分段错误.我相信这是争用条件的结果,因为它在程序执行期间的不同时间发生.这是我的evict_thread

I have a problem. I need to implement a program that switches ucontext threads using a timer and SIGALRM but I am getting a segmentation fault when I switch threads using my evict_thread function. I believe it is the result of a race condition as it occurs at different times durings the programs execution. Here is my evict_thread

void evict_thread(int signal)
{   
// Check that there is more than one thread in the queue
if ((int)list_length(runqueue) > 1)
{
    // Remove the currently executing thread from the runqueue and store its id
    int evict_thread_id = list_shift_int(runqueue);

    // Place the thread at the back of the run queue
    list_append_int(runqueue, evict_thread_id);

    // Get the id of the thread that is now at the head of the run queue
    int exec_thread_id = list_item_int(runqueue, 0);

    // Set the start time for new thread to the current time
    clock_gettime(CLOCK_REALTIME, &thread_table[exec_thread_id]->start);

    printf("Switching context from %s to %s\n",
        thread_table[evict_thread_id]->thread_name,
        thread_table[exec_thread_id]->thread_name);

    // Execute the thread at the head of the run queue
    if (swapcontext(&thread_table[evict_thread_id]->context, &thread_table[exec_thread_id]->context) == -1)
    {
        perror("swapcontext failed\n");
        printf("errno: %d.\n", errno);
        return;
    }   
}
return;     
}

上述功能按以下方式调用

The above function is called in the following manner

// Set the SIGALRM
if (sigset(SIGALRM, evict_thread) == -1)
{
    perror("sigset failed\n");
    printf("errno: %d.\n", errno);
    return;
}

// Initialize timer
thread_switcher.it_interval.tv_sec  = 0;
thread_switcher.it_interval.tv_usec = quantum_size;
thread_switcher.it_value.tv_sec = 0;
thread_switcher.it_value.tv_usec =  quantum_size;
setitimer(ITIMER_REAL, &thread_switcher, 0);

运行队列只是整数的全局列表,这些整数是指向ucontext线程的全局指针表的索引.使用来自libslack.org的C通用实用程序库中的list数据结构来实现该列表.

The run queue is simply a global list of integers that are indices into a global table of pointers to the ucontext threads. The list is implemented using the list data structure from a C general utility library available at libslack.org

当我禁用计时器并让每个线程在切换上下文之前运行完毕时,程序会正常运行,但是当执行期间切换线程时,大约80%的时间会出现分段错误.

When I disable the timer and let each thread run to completion before switching contexts the program runs properly, but when the threads are switched during execution I get a segmentation fault around 80% of the time.

此外,当我尝试使用gdb回溯分段错误时,它说它发生在系统调用中.

Also when I attempt to use gdb to backtrace the segmentation fault its says that it occurs within a systemcall.

推荐答案

猜想:您正在向内核传递不可见的内容,因为您切换了上下文.您正在询问段错误,但是您的代码正在做有趣的事情.

As a guess: you're passing something to the kernel that is not visible from there because you switch context. You are asking about a segfault, but your code is doing interesting things.

也许,如果您考虑使用更标准的线程调度模型,则可以避免这些问题. 除了尝试使用上下文切换来调度线程外,还有其他方法可以执行此操作.您可以使用完全相同的当前程序模型从逐出线程调用它们.

Perhaps if you considered a more standard model for thread scheduling you could avoid the problems. Instead of trying to schedule the threads using context switches there other ways to do this. And you could call them from your evict thread, using your exact same current program model.

其中一些建议是针对特定系统的.如果您可以告诉我们您的操作系统是什么,我们可以找到适合您情况的内容.或者,您也可以自己检查一下.

Some of this suggestion is a bit system specific. If you can tell us what your OS is we can find something that is good for your situation. Or you can check it out for yourself.

阅读有关POSIX线程调度的信息.请特别注意SCHED_FIFO,它将与您的模型一起使用.

Read about POSIX thread scheduling. Pay special attention to SCHED_FIFO, which will work with your model.

https://computing.llnl.gov/tutorials/pthreads/man/sched_setscheduler.txt

这通常适用于使用POSIX线程库来调度线程,而不是您尝试用困难的方式来完成.

This applies generally to using the POSIX thread library to schedule threads, instead of you trying to do it the hard way.

这篇关于使用SIGALRM切换线程上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆