C 언어 구현 다 중 스 레 드 타이머 인 스 턴 스 설명

1.대략적인 기능 소개
  • 작업 목록 을 실현 합 니 다.타이머 가 일정 시간 간격 으로 목록 을 옮 겨 다 니 며 수행 할 작업 을 발견 합 니 다
  • 퀘 스 트 목록 의 모든 퀘 스 트 병행 실행
  • 모든 퀘 스 트 는 자신의 타이머 가 있 고 중복 실행 여 부 를 선택 할 수 있 습 니 다
  • 편리 한 작업 함수 구현 인터페이스 정의
  • 타 이 머 는 사용자 가 언제 시작 하고 정지 할 지 사용자 정의 할 수 있 습 니 다
  • 대기 기능 을 제공 하여 퀘 스 트 목록 의 모든 퀘 스 트 수행 완성 을 보증 합 니 다
  • 퀘 스 트 목록 의 전 삼 기능 제공
  • 2.API 라 이브 러 리 소개
    
    void setTick(int val);
    시간 간격 tick 을 설정 합 니 다.tick 를 1000 으로 설정 하고 작업 의 타이머 시간 이 1000 이면 작업 은 1 초 후에 실 행 됩 니 다.기본 tick 는 1 초 이 고 최소 tick 시간 은 1us 입 니 다.
    
    void addTimerTask(TimerTask task, int val, int autoreset, void *arg);
    작업 목록 에 작업 을 등록 하고 정시 시간 val 을 지정 하 며 autoreset 를 반복 할 지 여 부 를 지정 하고 매개 변수의 주 소 를 지정 할 수 있 습 니 다.
    task 는 헤더 파일 이 제공 하 는 매크로 에 따라 작성 해 야 합 니 다.예 를 들 어:
    
    TASK_START(test2, arg)
    
    	//body
     Arg *temp = (Arg*)arg;
     temp->ret = temp->a + temp->b;
     printf("This is a test2
    "); TASK_END
    TASK_START(name,arg)는 퀘 스 트 헤드,name 은 퀘 스 트 이름,arg 는 매개 변수 주소,TASK엔 디 는 미 션 엔 딩.작업 내 에서 정상 적 인 c 언어 코드 를 작성 하고 인자 arg 지침 을 사용 할 수 있 습 니 다.
    autoreset 에는 AUTORESET(중복 실행),NORESET(한 번 실행)두 가지 옵션 이 있 습 니 다.
    인자 가 없 으 면 arg 인 자 를 NULL 로 설정 할 수 있 습 니 다.
    
    void TimerWait();
    작업 목록 의 모든 작업 이 완료 되 기 를 기다 리 는 데 사용 합 니 다.
    
    void TimerStop();
    
    타이머 정지 에 사용 합 니 다.
    
    void StartTimer();
    
    타이머 시작 에 사용 합 니 다.
    3.하나의 예
    
    #include <stdio.h>
    #include "timer.h"
    
    typedef struct Argument{
     int a;
     int b;
     int ret;
    }Arg;
    
    //  1,    
    TASK_START(test1, arg)
     printf("This is a test1
    "); TASK_END // 2, arg , TASK_START(test2, arg) Arg *temp = (Arg*)arg; temp->ret = temp->a + temp->b; printf("This is a test2
    "); TASK_END // 3, TASK_START(test3, arg) printf("This is a test3
    "); TASK_END void main(){ Arg arg; // tick 500ms setTick(500 * 1000); // 1 , 2.5s, , addTimerTask(test1, 5, AUTORESET, NULL); arg.a = 2; arg.b = 3; // 2 , 0.5s, , arg addTimerTask(test2, 1, NORESET, &arg); // 3 , 1s, , addTimerTask(test3, 2, AUTORESET, NULL); // StartTimer(); printf("Timer is started
    "); // 5 sleep(5); // TimerStop(); // TimerWait(); // printf("%d
    ", arg.ret); }
    실행 결과:

    4.라 이브 러 리 원본 코드
    timer.h:
    
    #ifndef TIMER_H
    #define TIMER_H
    #include <unistd.h>
    #include <stdio.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <signal.h>
    #define AUTORESET 1
    #define NORESET 0
    #define TASK_START(name, arg) void* name(void *arg){
    #define TASK_END return NULL;} 
    typedef void* (*TimerTask)(void* arg);
    struct TaskItem{
     TimerTask task;
     int init_counter;
     int counter;
     pthread_t th;
     void *arg;
     void *ret;
     int flag;
     int autoreset;
     struct TaskItem *next;
     
    };
    void setTick(int val);
    void* EventLoop(void* arg);
    void addTimerTask(TimerTask task, int val, int autoreset, void *arg);
    void TimerWait();
    void TimerStop();
    void StartTimer();
    #endif //TIMER_H
    
    timer.cpp
    
    #include "timer.h"
    #define STOPFLAG 0
    #define RUNFLAG 1 
    static int tick = 1000 * 1000;
    static struct TaskItem head = {
     .next = NULL,
    };
    static pthread_t loop_thread;
    static int flag = STOPFLAG;
    static int tasknum = 0;
    
    void setTick(int val){
     tick = val;
    }
    void* EventLoop(void* arg){
     
     struct TaskItem *task = head.next;
     struct TaskItem *pretask = &head;
    
     while(flag == RUNFLAG && tasknum > 0){
      
      while(task != NULL){
       if(task->counter == 0){ // it is time for doing task
        if(task->flag == STOPFLAG){ // task is not created
         if(0 != pthread_create(&(task->th), NULL, task->task, task->arg)){ // do a task
          printf("Failed to create user's task");
         }
         else{
          task->flag = RUNFLAG;
         }
        }
        else{
         if(0 != pthread_kill(task->th, 0)){ // current task is completed
          if(task->autoreset == AUTORESET){ // repeat execute
           task->counter = task->init_counter;
           task->flag = STOPFLAG;
          }
          else{ // delete a task
           pretask->next = task->next;
           free(task);
           task = pretask->next;
           tasknum--;
           continue;
          }
         }
        }
       }
       else{
        task->counter--;
       }
       pretask = pretask->next;
       task = task->next;
      }
      usleep(tick); // sleep a tick
      task = head.next;
      pretask = &head;
     }
     flag = STOPFLAG;
    }
    void addTimerTask(TimerTask task, int val, int autoreset, void *arg){
     struct TaskItem *node;
     node = (struct TaskItem*)malloc(sizeof(struct TaskItem));
     node->next = head.next;
     head.next = node;
     node->arg = arg;
     node->counter = val;
     node->init_counter = val;
     node->task = task;
     node->flag = STOPFLAG;
     node->autoreset = autoreset;
     tasknum++;
    }
    void TimerWait(){
     pthread_join(loop_thread, NULL);
    }
    void TimerStop(){
     flag = STOPFLAG;
    }
    void StartTimer(){
     flag = RUNFLAG;
     if(0 != pthread_create(&loop_thread, NULL, EventLoop, NULL)){
      printf("Failed to create loop task.
    "); } }
    주의 사항
  • 컴 파일 은-l pthread 옵션
  • 을 추가 해 야 합 니 다.
  • 라 이브 러 리 는 현재 Linux 환경 에 있 습 니 다.windows 라면 스 레 드 생 성 함수,휴면 함수 와 해당 하 는 헤더 파일 을 수정 해 야 합 니 다.
  • C 언어 구현 다 중 스 레 드 타이머 인 스 턴 스 설명 에 관 한 이 글 은 여기까지 입 니 다.더 많은 C 언어 가 다 중 스 레 드 타이머 내용 을 어떻게 실현 하 는 지 에 대해 서 는 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 지원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기