微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多次运行 pthread

如何解决多次运行 pthread

我想要一个线程无限次运行以执行它接收到的 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);
    
}

解决方法

您不是调用一个线程,而是创建一个线程。通过这样做,您指定了一个 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() 一直等到目标线程终止。通过加入线程,所有资源都归还给系统(清理)。

,

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

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

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

如果你们想测试代码,它会返回 do_work() 函数的执行时间,如果您的期间设置的截止日期丢失,则会返回一条消息。这项工作的目的是对周期线程进行类比。

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

运行: 须藤任务集 -c 0 ./exe 300 1 100000 F sudo taskset -c 0 ./exe 周期优先工作_负载调度器_策略

#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;

}

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。