LINUX.ORG.RU

Обработчик таймера для переключения контекста

 ,


0

1

Здравствуйте уважаемые форумчане. У меня следующая задача, в первом потоке (контексте) создается таймер и запускается отсчет времени, потом текущий контекст приостанавливается и запускается основной поток. По окончанию таймера снова нужно перейти на поток с таймером, но при текущем коде выдает ошибку сегментации. Я так понял обработчик создает еще один поток и проблема именно в этом, тогда как сделать так чтобы обработчик относился к основному потоку? Заранее спасибо за ответы.

void alarm_handler()
{
   printf("Check timer\n");
   Run_my_thread(temp);
   return;
}
void yield_Thread(int second, int usecond)
{
printf("Timer start\n");
signal(SIGALRM, alarm_handler);
  if(second!=0) timer.it_value.tv_sec = second;
  else if(usecond!=0) timer.it_value.tv_usec = usecond;
  timer.it_interval.tv_sec = 0;
  timer.it_interval.tv_usec = 0;
   printf("Next string start alarm\n");
 setitimer(ITIMER_REAL, &timer, NULL);
   Stop_cur_Thread();
}
void Stop_cur_Thread()
{
tempstate="Sleep";
swapcontext(&nextThread, &prevThread);
}
void Run_my_thread(My_Thread *runThread)
{
getcontext(&prevThread);
swapcontext(&prevThread, &runThread->context);
printf("Ve return to maint context\n");
if(tempstate=="Sleep"){
runThread->state="Sleep";
runThread->context=nextThread;
}



Последнее исправление: Slonichek (всего исправлений: 1)
Ответ на: комментарий от xpahos

Что-то типа этого?

Вроде так, но не видит pthread_sigmask с #include <pthread.h>.

struct sigaction new_action;
new_action.sa_handler = alarm_handler;
sigemptyset(&new_action.sa_mask);
int rc = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, NULL);
new_action.sa_flags = 0;
sigaction (SIGALRM, &new_action, NULL);

Slonichek
() автор топика
Ответ на: комментарий от xpahos

Полный код

#include <ucontext.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
struct itimerval timer;
typedef struct My_Thread_s{
char *state;
int id;
ucontext_t context;
struct My_Thread_s *next;
}My_Thread;
My_Thread *start;
My_Thread *temp;
char *tempstate;
ucontext_t prevThread;
ucontext_t nextThread;
ucontext_t Create_my_thread(void (*funk_add)())
{
   ucontext_t uctx_func1, uctx_main;
    getcontext(&uctx_main);
    char func1_stack[16384];
   if (getcontext(&uctx_func1) == -1)
    handle_error("getcontext");
    uctx_func1.uc_stack.ss_sp = func1_stack;
    uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
    uctx_func1.uc_link = &uctx_main;
    makecontext(&uctx_func1, funk_add, 0);
    return uctx_func1;
}
void Run_my_thread(My_Thread *runThread)
{
getcontext(&prevThread);
swapcontext(&prevThread, &runThread->context);
//if(runThread==NULL)return;
if(tempstate=="Sleep"){
runThread->state="Sleep";
runThread->context=nextThread;
}
else
runThread->state="Finished";
}
void Sleep_my_Thread(int second)
{
printf("We sleep ...\n");
sleep(second);
}
void Stop_cur_Thread()
{
//nextThread=temp->context;
tempstate="Sleep";
getcontext(&nextThread);
swapcontext(&nextThread, &prevThread);
}
void alarm_handler()
{
   printf("Check timer\n");
   //temp->context=nextThread;
   getcontext(&prevThread);
   Run_my_thread(temp);
   return;
}
void yield_Thread(int second, int usecond)
{
printf("Timer start\n");
struct sigaction new_action;
new_action.sa_handler = alarm_handler;
sigemptyset(&new_action.sa_mask);
sigaddset(&new_action.sa_mask, SIGQUIT);
sigaddset(&new_action.sa_mask, SIGUSR1);
//sigaddset(&new_action.sa_mask, SIGQUIT);
//sigaddset(&new_action.sa_mask, SIGUSR1);
int rc = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, NULL);
new_action.sa_flags = 0;
sigaction (SIGALRM, &new_action, NULL);
  if(second!=0) timer.it_value.tv_sec = second;
  else if(usecond!=0) timer.it_value.tv_usec = usecond;
  timer.it_interval.tv_sec = 0;
  timer.it_interval.tv_usec = 0;
   printf("Next string start alarm\n");
 setitimer(ITIMER_REAL, &timer, NULL);
Stop_cur_Thread();
}
int Delete_Thread(My_Thread *start, int id){
My_Thread *next=start->next;
My_Thread *prev=start;
while(next!=0){
if(next->id==id){
prev->next=next->next;
free(next);
return 1;
}
prev=next;
next=next->next;
}
return 0;
}
static void func1(void)
{
int i=0;
    printf("func1: started\n");
    printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
    Stop_cur_Thread();
    //Sleep_my_Thread(5);
    yield_Thread(5,0);
    printf("func1: returning\n");
    //Stop_cur_Thread();
    return;
}
int main(int argc, char *argv[])
       {
        My_Thread *temp=malloc(sizeof(My_Thread));
        getcontext(&temp->context);
        temp->next=0;
        temp->id=0;
        start=temp;
        printf("Progtram start\n");
        temp->next=malloc(sizeof(My_Thread));
        temp=temp->next;
        temp->context=Create_my_thread(func1);
        temp->next=0;
        temp->id=1;
        temp->state="OK";
        Run_my_thread(temp);
        Run_my_thread(temp);
        //while(1){printf("work\n");sleep(1);}
        if(Delete_Thread(start, 1)==1) printf("OK\n");
        else printf("Error in delete\n");
        sleep(6);
        printf("Program return\n");
        exit(EXIT_SUCCESS);
       }
Slonichek
() автор топика
Ответ на: Полный код от Slonichek

char *tempstate; - ты заявляешь что-то у тебя должен быть набор байт и ссылаешься на него. Тут тоже нужен malloc.

tempstate==«Sleep» так делать нельзя, в C строк нет, это массив байт. есть strncmp, для присвоения strncpy и не забывай что «\0» ты руками добавляешь для каждой строки.

        temp->next=malloc(sizeof(My_Thread));
        temp=temp->next;
        temp->context=Create_my_thread(func1);
        temp->next=0;
        temp->id=1;
        temp->state="OK";
        Run_my_thread(temp);
        Run_my_thread(temp);

ты пытаешься итерироваться по односвязному списку, а потом два раза запустить что-то странное. После вызова temp->next = malloc, temp = temp->next; temp будет указывать на пустую структуру и когда вызовется alarm_hander он будет пытаться обратиться к твоей пустой структуре.

xpahos ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.