2009-06-03 6 views
0

C에서 동시 트랜잭션 라이브러리를 작성 중이며 다음 문제점을 발견했습니다. 의는 "트랜잭션"트랜잭션 마스터와 통신 채널을 나타내는 샘플 거래 회원의 의사 코드를 생각해 보자 : 우리는 마스터에 의해 투표를 요구하는 경우에만 동시 트랜잭션에서goto로 C에서 예외를 시뮬레이트하는 방법은 무엇입니까?

transaction = trans_join(); 

do_some_ops(); 

/* receive the data from the master */ 
trans_rcv(transaction, data); 

do_some_ops(); 

trans_send(transaction, answer); 

/* wait for the possibility for voting */ 
trans_ready(transaction); 

/* vote for commiting and wait for the voting results. */ 
if(trans_commit(answer)) 
{ 
    printf("Final commiting the changes.\n"); 
} 
else 
{ 
    printf("Rolling back the changes.\n"); 
} 

, 우리는 투표 할 수 있습니다. 그러나 마스터는 언제든지 trans_abort(member)에 전화하여 지정된 구성원이 트랜잭션을 취소하도록 할 수 있습니다. ABORT 메시지는 모든 실행 단계에서 구성원이 수신 할 수 있으며이 경우 비공식적으로 호출이 trans_ready() 호출에 도달 할 때까지 기다리지 않아야합니다. 예를 들어, 이후 코드에 trans_rcv() 호출이 있으면 마스터에서 보내지 않은 데이터를 기다리는 동안 프로세스가 중단됩니다.

이제 요점. 나는 이미 변경 사항을 롤백하는 중단 기능을 등록하는 코드를 가지고 있지만 나머지 작업을 건너 뛰고 즉시 투표 코드로 이동할 수있는 추가 메커니즘을 갖고 싶습니다. 나는 아이디어가 예외를 시뮬레이션하기 위해 여기 고토를 사용할 필요가 : 그러나

if(!trans_rcv()) /* fail, we received the abort message */ 
{ 
    goto abort_code; 
} 

... 

abort_code: 
trans_ready(transaction); 
/* etc. */ 

, trans_rcv 또는 trans_send의 모든 통화에 대해 IFS 를 작성하는 것은 트랜잭션 코드가 복잡 특히, 매우 편안하지 않습니다. 더 나은 솔루션에 대한 아이디어가 있습니까? 아니면 유일한 방법입니까? 그런데 goto을 사용할 필요가 없습니다. :) trans_rcv 매개 변수가있는 경우

#define trans_rcv_CHK do { \ 
    if (!trans_rcv()) \ 
    { \ 
      goto abort_code; \ 
    } \ 
} while(0) 

, 이것은 (적어도, GCC의) 작동합니다 :

#define trans_rcv_CHK(...) do { \ 
    if (!trans_rcv(__VA_ARGS__)) \ 
    { \ 
      goto abort_code; \ 
    } \ 
} while (0) 
+0

"goto? AAAAAAAAAAAARGH"와 같은 사람들이 몇 명이나 올지 알아 보겠습니다. P –

+0

goto? –

답변

5

, 당신은 같은 매크로를 사용할 수 있습니다 개인적으로 나는 스위치 내부의 상태 머신을 가진 while 루프를 사용하여 이것을 코드화 할 것이다.

+1

매크로 ... 얼마나 이상한 지 잊어 버렸습니다. 미리 감사드립니다! – Zyx

+2

거짓인지 확인하면서 if를 감싸는 지 확인하십시오. 마지막으로 trans_rcv_CHK를 세미콜론으로 호출하고 의도하지 않은 결과가 발생하지 않도록하십시오. 참조 : http://c2.com/cgi/wiki/Wiki?TrivialDoWhileLoop –

+1

@sharth : 좋은 지적, 고마워. 대답에 루프를 추가했습니다. – tsg

3

IFS의를 입력하면 문제가 될 경우

7

goto은 하나의 함수 내에서만 작동하며 예외 메커니즘에 대한 제한이 너무 많습니다.

자세한 내용은 setjmp/longjmp 기능을 사용하는 것이 좋습니다. 자세한 내용은 Wikipedia을 참조하십시오.

3

exception handling in C의 가장 좋은 소스 중 하나입니다. 기본적으로 RTOS의 사람들이 RTFile 모듈에 대해 예외를 구현 한 방법. 기사의 후반부를 지나서 어셈블리 언어로의 무서운 미끄러짐을 조심하십시오.