2014-03-18 1 views
0

주 스레드에서 여러 스레드 (4 스레드)를 만들었습니다. 모든 스레드가 동일한 기능을 실행하는 동안 스레드 예약이 예상 한 것과 같지 않습니다. OS에 대한 나의 이해에 따라, 리눅스 CFS 스케줄러는 "t"가상 실행 시간 퀀텀을 할당하고 해당 시간 퀀텀의 만료시 CPU가 현재 스레드에서 우선 사용되며 다음 스레드에 할당됩니다. 이 방식으로 모든 스레드가 CPU를 공평하게 공유하게됩니다. 내가 얻는 것은 기대에 따른 것이 아니다.CFS에서 멀티 스레딩 시나리오에서 예기치 않은 결과가 발생했습니다. CFS schedualar

모든 스레드 (스레드 1-4, 주 스레드)가 동일한 스레드 (모두)가 다음에 CPU를 확보하기 전에 CPU를 확보 할 것으로 예상됩니다. : 00 : 17 : 이제> (1) ---> 시간 -

예상 출력은

foo3입니다 45.346225000

foo3 -> 1 ---> 시간 현재 : 0시 17분 : 45.348818000

foo4 -> 1 ---> 이제 시간 : 00 : 17 : 45.350216000

foo4 - 지금> 1 ---> 시간 : 00 : 17 : 주요 45.352800000

실행 ---> 1- -> 이제 시간 : 00 : 17 : 45.355803000

주요 실행 ---> 1 ---> 시간 현재 : 00 : 17 : 45.360606000

에서는 foo2 -> 1 ---> 시간 현재 : 00 : 17 : 45.345305000

에서는 foo2 - 지금> 1 ---> 시간 : 00 : 17 : 45.361666000

foo1은 -> 1 ---> 시간 현재 : 00 : 17 : 45.354203000

foo1 -> 1 ---> 시간 : 00 : 17 : 45.362696000

foo1 -> 2 ---> 이제 시간 : 00 : 17 : 45.362716000 // foo1은 스레드가

foo1은 예상대로 CPU 2 시간 있어요 - 지금> 2 ---> 시간 : 00 : 17 : 45.365306000

하지만

무엇입니까를

foo3 - 지금> 1 ---> 시간 : 00 : 17 : 45.346225000

foo3 - 지금> 1 ---> 시간 : 00 : 17 : 45.348818000

foo4-- > 1 ---> 시간 : 00 : 17 : 45.350216000

foo4 -> 1 ---> 이제 시간 : 00 : 17 : 45.352800000

주요 실행 ---> 1 ---> 시간 현재 : 00 : 17 : 45.355803000

주 실행 중 ---> 1 ---> 시간 : 00 : 17 : 45.360606000

foo3 -> 2 ---> 시간 : 00 : 17 : 45.345305000 // foo3 스레드는 CPU 두 번째 시간을 가짐 CFS 당 다른 스레드를 예약하기 전에 UNEXPECTEDLY로

foo3 -> 2 ---> 지금 시간 : 00:17:45.361,666,000

foo1은 -> 1 ---> 이제 시간 : 00 : 17 : 45.354203000

foo1은 - 이제> (1) ---> 시간 : 00 : 17 : 45.362696000

foo1은 - 이제> 2 ---> 시간 : 00 : 17 : 45.362716000

foo1은 -> 2 ---> 시간 현재 : 00 : 17 : 여기 45.365306000

내 프로그램 (이다 thread_multi.c PP)

여기
#include <pthread.h> 
#include <stdio.h> 
#include "boost/date_time/posix_time/posix_time.hpp" 
#include <iostream> 
#include <cstdlib> 
#include <fstream> 
#define NUM_THREADS 4 

using namespace std; 

std::string now_str() 
{ 
    // Get current time from the clock, using microseconds resolution 
    const boost::posix_time::ptime now = 
     boost::posix_time::microsec_clock::local_time(); 

    // Get the time offset in current day 
    const boost::posix_time::time_duration td = now.time_of_day(); 
    const long hours  = td.hours(); 
    const long minutes  = td.minutes(); 
    const long seconds  = td.seconds(); 


    const long nanoseconds = td.total_nanoseconds() - ((hours * 3600 + minutes * 60 + seconds) * 1000000000); 
    char buf[40]; 

    sprintf(buf, "Time Now : %02ld:%02ld:%02ld.%03ld", hours, minutes, seconds, nanoseconds); 
    return buf; 
} 


/* This is our thread function. It is like main(), but for a thread*/ 
void *threadFunc(void *arg) 
{ 
    char *str; 
    int i = 0; 

    str=(char*)arg; 

    while(i < 100) 
    { 

     ++i; 
     ofstream myfile ("example.txt", ios::out | ios::app | ios::binary); 

     if (myfile.is_open()) 
      { 
      myfile << str <<"-->"<<i<<"--->" <<now_str() <<" \n"; 

      } 
      else cout << "Unable to open file"; 
     // generate delay 
     for(volatile int k=0;k<1000000;k++); 



     if (myfile.is_open()) 
      { 
      myfile << str <<"-->"<<i<<"--->" <<now_str() <<"\n\n"; 
      myfile.close(); 
      } 
      else cout << "Unable to open file"; 
    } 


} 

int main(void) 
{ 
    pthread_t pth[NUM_THREADS]; // this is our thread identifier 
    int i = 0; 

    pthread_create(&pth[0],NULL, threadFunc, (void *) "foo1"); 
    pthread_create(&pth[1],NULL, threadFunc, (void *) "foo2"); 
    pthread_create(&pth[2],NULL, threadFunc, (void *) "foo3"); 
    pthread_create(&pth[3],NULL, threadFunc, (void *) "foo4"); 



std::cout <<".............\n" <<now_str() << '\n';  

    while(i < 100) 
    { 

     for(int k=0;k<1000000;k++); 

     ofstream myfile ("example.txt", ios::out | ios::app | ios::binary); 
      if (myfile.is_open()) 
      { 
      myfile << "main is running ---> "<< i <<"--->"<<now_str() <<'\n'; 
      myfile.close(); 
      } 
      else cout << "Unable to open file"; 


     ++i; 
    } 

// printf("main waiting for thread to terminate...\n"); 
    for(int k=0;k<4;k++) 
    pthread_join(pth[k],NULL); 

std::cout <<".............\n" <<now_str() << '\n';  
    return 0; 
} 

가 완전히 페어 스케줄러 상세

kernel.sched_min_granularity_ns = 100,000 kernel.sched_wakeup_granularity_ns kernel.sched_latency_ns = 25,000 = 1,000,000

sched_min_granularity_ns 값당 같은 임의 작업이 최소 시간 동안 실행되고 작업에 최소 시간 이상이 필요한 경우 시간 조각이 계산되고 모든 작업이 그 시간 조각을 위해 실행. 수식을 이용하여 계산된다

여기

타임 슬라이스

타임 슬라이스 = (실행 큐 CFS 미만 각 태스크 태스크/총 중량의 중량) × sched_latency_ns

수 왜 내가 스케줄링의 결과를 얻고 있는지 설명하는 사람은 누구입니까? 출력물을 이해하는 데 도움이 될 것입니다. 미리 감사드립니다.

저는 리눅스에서 gcc를 사용하고 있습니다.

EDIT 1 : I가이 루프

바꾸면

(INT의 K를 = 0; k는 100,000 < k 번째 ++); (k 번째 < 10000; 케이 ++ INT에서 K = 0)에 대한

;

다음 때때로 쓰레드 (1)가 10 회 연속하여 CPU있어, 실이 연속하여 5 회 CPU있어, 실 (3)이 2 회 연속해서, 연속 5 회 메인 쓰레드 CPU를 가지고, 나사 (4)가 연속적으로 7 회 CPU를 얻었다. 다른 스레드가 임의의 시간에 선점 된 것처럼 보입니다.

다른 스레드에 연속적으로 CPU를 할당하는 임의의 시간에 대한 단서. ??

답변

0

CPU가 각 스레드를 실행하는 데 약간의 시간을 할당합니다.각 스레드가 동일한 인쇄 매수를하지 않는 이유는 무엇입니까?

내가 예에서이 문제를 설명 할 것이다 :

당신이 컴퓨터 1 인쇄 할 가 인정 NS 100 개 지침을 만들 수 있다는 것을 인정하는 것은 각 스레드가

을 작업 1NS을 가지고 있음을 인정 (25 개)의 지침을 사용하는 것과 동일

컴퓨터의 모든 프로그램이 100 개의 사용 가능한 명령어를 처리하고 있음을 이해해야합니다.

스레드가 무언가를 인쇄하려면 100 개의 명령어를 사용할 수 있으면 4 개의 문장을 인쇄 할 수 있습니다. 스레드가 무언가를 인쇄 할 때 40 개의 명령어를 사용할 수 있으면 1 문장을 인쇄 할 수 있습니다. 다른 프로그램이 지침을 사용하기 때문에 40 개의 명령어 만 있습니다.

들으시겠습니까?

질문이 있으시면 언제든지 환영합니다. :)

관련 문제