초보 nginx 소스 코드 분석 데이터 구조 편 (10) 자전 자물쇠 ngxspinlock


초보 nginx 소스 코드 분석 데이터 구조 편 (10) 자전 자물쇠 ngxspinlock
 
  • 작성 자: Echo Chen (진 빈)
  • Email:[email protected]
  • Blog:Blog.csdn.net/chen19870707
  • Date:Nov 11th, 2014           자 회전 자물쇠 (Spinlock) 는 리 눅 스 커 널 에서 광범 위 하 게 사용 되 는 바 텀 동기 화 체제 이다.자전 자 물 쇠 는 다 중 프로세서 환경 에서 작 동 하 는 특수 한 자물쇠 로 단일 처리 환경 에서 자전 자 물 쇠 를 사용 하 는 작업 이 빈 작업 으로 바 뀌 었 다.어떤 프로세서 의 커 널 실행 스 레 드 가 자전 자 물 쇠 를 신청 할 때 잠 금 을 사용 할 수 있 으 면 자 물 쇠 를 얻 은 다음 임계 구역 작업 을 수행 하고 마지막 으로 자 물 쇠 를 방출 합 니 다.잠 금 이 점용 되면 스 레 드 는 수면 상태 로 들 어가 지 않 고 잠 금 을 기다 리 느 라 바 쁘 며 잠 금 이 풀 리 면 이 정 보 를 감지 하 는 첫 번 째 스 레 드 는 잠 금 을 얻 을 수 있 습 니 다.1. 소스 코드 위치  원본 파일:http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_spinlock.c   2. 관련 구조 정의
    원자 잠 금 구조 ngxatomic_t:
       1: typedef unsigned long               ngx_atomic_uint_t;
       2: typedef volatile ngx_atomic_uint_t  ngx_atomic_t;

    원자 잠 금 값 유형 ngxatomic_int_t:
       1: typedef long                        ngx_atomic_int_t;

    원자의 비교 와 교환, lock 과 old 가 같 으 면 set 는 lock 에 기록 합 니 다.
       1: #define ngx_atomic_cmp_set(lock, old, set)                                    \
       2:     __sync_bool_compare_and_swap(lock, old, set)

    설명:
    bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)        type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
    이 두 함 수 는 GCC 가 원자의 비교 와 교환 을 제공 하 는 것 으로 * ptr = = oldval 이면 new val 을 * ptr 에 기록 합 니 다.
    프로 세 스 가 주동 적 으로 집행 권 을 양보 합 니 다, ngxsched_yeld
       1: #define ngx_sched_yield()  sched_yield()

    3. 소스 코드 분석
       1: void
       2: ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
       3: {
       4:  
       5: #if (NGX_HAVE_ATOMIC_OPS)
       6:  
       7:     ngx_uint_t  i, n;
       8:  
       9:  
      10:     for ( ;; ) {
      11:  
      12:         //*lock == 0,       ,   ngx_atomic_cmp_set  ,  *lock=value,     
      13:         if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
      14:             return;
      15:         }
      16:         
      17:         //   
      18:         if (ngx_ncpu > 1) {
      19:             
      20:             //   spin   80,       1   ngx_cpu_pause()   ,           。          2 、4  、8  、16  、32  、64   ngx_cpu_pause()      。
      21:               //                       ,       ,spinlock       。         ,    ngx_sched_yield,          。
      22:             for (n = 1; n < spin; n <<= 1) {
      23:  
      24:                 for (i = 0; i < n; i++) {
      25:                     ngx_cpu_pause();
      26:                 }
      27:                 
      28:                 //      ,   *lock == 0,       
      29:                 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
      30:                     return;
      31:                 }
      32:             }
      33:         }
      34:         
      35:         //  CPU   
      36:         ngx_sched_yield();
      37:     }
      38:  
      39: #else
      40:  
      41: #if (NGX_THREADS)
      42:  
      43: #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
      44:  
      45: #endif
      46:  
      47: #endif
      48:  
      49: }

     
  • 4. 참고 자료  1.http://blog.csdn.net/poechant/article/details/8062969 2.
  •  
  • -Echo Chen
  • Blog.csdn.net/chen19870707
  • -
  • 좋은 웹페이지 즐겨찾기