0

我希望一个线程运行无限次,以执行它接收到的 do_work() 函数中描述的任务。但是,该函数仅在 pthread_create() 子例程上调用。

我尝试在 while 循环中实现 sched_yield() 和 pthread_join() 例程。但它还没有奏效。

有没有可以再次调用现有线程的例程?

int main (int argc, char ** argv) {

    int period;
    int priority;
    int load;
    char schedule[15];
    
    period = atoi(argv[1]);
    priority = atoi(argv[2]);
    load = atoi(argv[3]);
    strncpy(schedule,argv[4],100);
    std::cout <<  " period : " << period <<"\n priority : "<< priority << "\n load : "<< load << "\n schedule : " << schedule <<std::endl;
    

    struct sched_param param;   
    pthread_t thread;
    int rc;
    sched_setscheduler (0, SCHED_FIFO , &param);

    
    std::cout << "main() : creating thread " << std::endl;
    rc = pthread_create(&thread, NULL, do_work, (void*)load);

    if (rc) {
         std::cout << "Error:unable to create thread " << rc << std::endl;
         exit(-1);
    }
    
    int i=0;
    
    struct sigaction action;
    struct itimerval timer;
    
    while(i<10000){
        pthread_join(thread, NULL);
        sched_yield();

        i++;
    }
    pthread_exit(NULL);
    
}
4

2 回答 2

1

您不调用线程,而是创建线程。通过这样做,您指定了一个将在新线程中调用的start_routine 。

如果要在循环中重复调用函数,则可以在start_routine中执行以下操作:

void* start_routine(void *arg) {
    while (active) { // active: atomic global boolean value
        do_work();
    }
    // if no longer active, 
    // there could be an option to wait to become active again,
    // or exit the thread
    pthread_exit(NULL);
}

pthread_join()仅在您想将线程与其他线程连接时才调用pthread_join()一直等到目标线程终止。通过加入线程,所有资源都归还给系统(清理)。

于 2021-03-12T14:34:13.093 回答
0

只是想向您展示我实现的代码。

当我提出这个问题时,我不确定线程​​的含义,您帮助我理解我无法多次访问线程上的函数,但我必须在每次使用时创建它。

我的主要目标是找到一种在接收信号 SIGALRM 时调用 do_work() 函数的方法。因此,我只是假设 do_wordk() 是我的线程并使用 sigaction 结构来控制信号的到达。

如果你们想测试代码,它会返回 do_work() 函数的执行时间,并在您的期限设置的最后期限丢失时返回一条消息。这项工作的目的是与周期性线程进行类比。

编译:g++ teste.cpp -o exe -lrt

运行: sudo taskset -c 0 ./exe 300 1 100000 F sudo taskset -c 0 ./exe Period Priority Work_Load Scheduler_Policy

#include<signal.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<sys/time.h>
#include<iostream>
#include<string>
#include<string.h>


long load=1;
void deadline();
void do_work();



void wakeup(int j){
    struct itimerval aux;
    int t1, t2;
    
    getitimer( ITIMER_REAL, &aux);  //Get initial resume time
    
    t1 = aux.it_value.tv_usec;
    //std::cout << "Hello World! Thread working |Resume Time : " <<t1<< std::endl;
    
    do_work();
    
    getitimer( ITIMER_REAL, &aux);
    t2 = aux.it_value.tv_usec; //Get Final resume time
    
    std::cout << "Execution time (usec): " <<t1 - t2<< std::endl;
    
    if (t2==0){
        deadline();
    }
    return;
}

void do_work(){
    
    for ( int i = 0; i < load * 1000; i++) {
        /* do nothing , keep counting */
    }

}

void deadline() {
    std::cout << "Lost deadline!" <<  std::endl;
}

int main (int argc, char ** argv) {
    int i;
    int period;
    int priority;
    char scheduler[5];
    
    period = atoi(argv[1])*1000;
    priority = atoi(argv[2]);
    load = atoi(argv[3]);
    strcpy(scheduler, argv[4]);
    
    std::cout <<  " period : " << period <<"\n priority : "<< priority << "\n load : "<< load << "\n scheduler : " << scheduler <<std::endl;
    
    struct sched_param param;   
    param.sched_priority = priority;
    
    if (scheduler[0]=='F'){
        int r = sched_setscheduler (0, SCHED_FIFO , &param);
        if(r==-1){ perror("scheduller"); return 1;}
        std::cout <<"FIFO scheduller: "<<r<<std::endl;
        
    }else{
        int r = sched_setscheduler (0, SCHED_RR , &param);
        if(r==-1){ perror("scheduller"); return 1;}
        std::cout <<"RR scheduller: "<<r<<std::endl;
    }
    
    struct itimerval val;
    struct sigaction action;
    sigset_t mask;
    
    sigemptyset(&action.sa_mask);
    action.sa_handler = wakeup;
    action.sa_flags=SA_RESTART; 
    
    if(sigaction(SIGALRM, &action, 0)==-1){
        perror("sigaction");
        return 1;
    }
    
    
    val.it_interval.tv_sec=0;
    val.it_interval.tv_usec=period;
    val.it_value.tv_sec=0;
    val.it_value.tv_usec=period;
    
    if(setitimer(ITIMER_REAL, &val, 0)==-1){
        perror("setitimer");
        return 1;
    }
    
    if(sigwait( &mask, &i)==-1){
        perror("sigwait");
    }
    
    
    return 0;

}

最后,非常感谢您耐心地理解我的问题。这是我对这个社区的第一个问题,我希望随着时间的推移我会改进它们。谢谢大家的回答和帮助我的努力。

于 2021-03-23T15:55:44.070 回答