2014-09-27 2 views
2

클라이언트의 데이터를 처리하는 다른 서버로 보내는 서버 프로그램이 있습니다. 하지만 함수가 실행되기까지 오랜 시간이 걸리고 프로그램이 다른 클라이언트의 데이터에서 작동하지 못하기 때문에 pthread를 사용하거나 프로세스를 만들지 않고도 다른 사람들의 데이터에 대해 동일한 함수를 동시에 실행하려고합니다.스레드를 사용하지 않고 동시에 함수를 실행하는 방법

나는 그것을 할 수있는 무언가를 만들려고했으나 추악하고 확실하게 최선의 방법은 아닙니다. 여기에 내 코드입니다 :

#include <stdio.h> 
#include <string.h> 
#include <vector> 

struct userdata { 
    int rt; //The 'func' function uses it to resume work where it returned the last time 
    int len; //The length of 'data' 
    char data[16384]; //Client's data 
}; 

int func(userdata *ud) 
{ 
    //The gotos are here to jump to the code where the function returned the last time 
    if(ud->rt==1)goto P1; 
    if(ud->rt==2)goto P2; 

    ud->len=0; 

    //Code to calculate the length of 'data' 
    while(ud->data[ud->len]!=0) 
    { 
     ud->rt=1; //Set to 1 to indicate where to resume execution the next time we will process the same data 
     return 0; 
     P1: 
     ud->len++; 
    } 
    // Work 
    ud->rt=2; 
    return 0; 
    P2: 
    // Work 

    return 1; 
} 

int main(int argc, char *argv[]) 
{ 
    userdata ud; 
    memset(ud.data,1,16383); 
    ud.data[16383]=0; 

    std::vector<userdata> vec; 
    for(int i=0;i!=200;i++)vec.push_back(ud); //Add 200 times the structure in the vector 
    unsigned int Sz=vec.size(); //I'll use Sz in the for loop to avoid calling size() 

    bool Loop=true; 
    do 
    { 
     for(int i=0;i!=Sz;i++) 
     { 
      if(func(&vec.at(i))==1) //If the function returned 1 this means that there's no more work to do 
      { 
       printf("str length = %i\n",vec.at(i).len); //Display the result 
       vec.erase(vec.begin() + i); //Remove element from vector because there's no more work to do 
       i--, Sz--; //Decrement Sz (size of the vector) and i (vector index) to avoid out_of_range exception 
       if(Sz==0)Loop=false; //If there are no elements in the vector, leave Loop 
      } 
     } 
    } 
    while(Loop); 

    return 0; 
} 

여기에서의 문제는이, 나는 구조에서 마지막 상태로 복원해야하며,이 벡터 시간이 많이 걸릴 수있는 변수를 배치해야합니다 동시 실행이되지 않는 것입니다 수천 개의 요소를 포함합니다.

+6

여기서 동시성은 어디에 있습니까? 나는이 질문이 무엇에 관한 지 전혀 모른다. 귀하의 코드는 진흙처럼 명확하고 코멘트를 기록하지 않습니다. 왜? –

+0

글쎄, 일종의 _ 시그널 인터럽트/반응 _ 방법을 [co-routines]라고 불리는 실행을 조직하는 방법이 있습니다. (http://stackoverflow.com/questions/121757/how-do-you-implement-coroutines-in- 기음). 나는 이것이 당신이하려는 것을 실제로 도울 것이라고 확신하지는 않지만. –

+0

@LightnessRacesinOrbit _ "동시성은 어디에 있습니까?"OP는 그것을 피할 수 있었기 때문에 분명하지 않습니다. –

답변

1

자신의 범용 스레딩 라이브러리를 작성하지 마십시오. pthread보다 비용이 많이 듭니다. 대신, 특정 문제의 지식을 사용하여 문제를 분리하십시오. 의 의미가 인 장소를 찾습니다.

나는 이미 select/poll/epoll을 호출하는 메인 루프가 있다고 가정합니다. 시간 제한이 아직 없으면 하나를 사용하여 추가, 시간 초과, 심지어 트리거 집합을 힙에 저장할 수 있습니다.

각 계산에서 특정 반복 횟수 후에 함수 + 데이터를 호출하도록 예약합니다. 현재 시간은입니다 (현재 타이머 이벤트가 실행되기 시작한 시점과 반대가됩니다). 시간이 실제로 지나면 타이머 디스패처는 새 트릭의 다음 단계 (약 라운드 로빈 스케줄러의 동작)를 계속하기 전에 가장 오래된 체크에 대한 모든 계산을 먼저 마칩니다. 이 아니라이 슬라이스 크기를 너무 작게 만들려고하거나 작업 전환 오버 헤드가 우세하기 시작합니다.

문제 세트에 따라 관련 클라이언트가 사망하는 경우 향후 타이머를 취소하는 논리를 추가하거나 원하지 않을 수도 있습니다.

+0

"자신 만의 범용 스레딩 라이브러리를 작성하지 마십시오."라는 질문에 대한 대답과는 아무 관련이 없습니다. –

+2

@MichaelGazonda 그것은 OP의 * 코드 *가 쓰여지는 방식과 관련하여 * 모든 것을 가지고 있습니다. – o11c

+0

은 의견이 아닌 답, 그리고 분명히 시작 단락의 문제와 비슷하게 들립니다. –

0

바퀴를 재발 명하려고 시도하지 마십시오. 스레딩 메커니즘은 어렵습니다. 당신이하는 일은 당신의 시스템이 제공하는 것보다 더 벅차고 느릴 것입니다.

함수에서 사용하는 데이터 구조 안팎으로 데이터를 복사하는 것은 이상한 접근 방식입니다. 당신은 어디에 넣을까요? 스레딩에 대한 일반적인 접근 방법은 스레드 당 하나의 스택을 갖는 것입니다 (각 스레드는 호출 스택과 데이터 스택을 모두 가지고 있습니다). 각 스레드는 함수의 한 인스턴스를 실행하고 힙에 메모리가 할당되면 문제의 각 인스턴스가 서로 다른 힙 위치에 저장됩니다. 따라서 각 스레드의 스택과 레지스터에는 다른 힙 영역에 대한 포인터가 포함됩니다.

+1

"바퀴를 재발 명하려고하지 마십시오. 쓰레딩 메커니즘은 어렵습니다. 당신이하는 일은 무엇이든 당신의 시스템이 제공하는 것보다 더 벅차고 느려질 것입니다." 질문에 대답하려고 시도하지 않으며 질문을 질문하는 부분에 특정 의도가 있음을 암시합니다. –

+0

@MichaelGazonda 질문을 읽는 것이 좋습니다. 제목으로 시작하기 - "스레드를 사용하지 않고 동시에 함수를 실행하는 방법", 그리고 질문 본문, 특히 마지막 단락을 계속 진행하십시오. 동시에 함수의 [여러 인스턴스]를 실행하는 것은 스레딩 메커니즘입니다 (이름으로 호출했는지 여부에 관계없이 스레드를 덜 생성하지는 않습니다). 두 번째 단락은 질문의 마지막 단락에서 설명한 컨텍스트 전환에 대한 접근 방법을 다룹니다. – Gilles

+0

@ Gilles하지만 스레드보다 가벼운 것이 있습니까? 여러 웹 사이트에서 최대 스레드 수가 매우 높지는 않다고 읽었습니다. 나는 어딘가에 32000을 보았다. 나를 위해 충분하지 않습니다. – Echren

관련 문제