2017-04-12 1 views
0

필자는 개인적으로 구현 한 데이터 구조를 가지고 있으며 이제는 여러 스레드에서 사용해야합니다.C - 내 데이터 구조 구현을 동기화하는 방법?

typedef struct 
{ 
    void** array_of_elements; 
    size_t size; 
} myStruct; 

단순 들어, 내 데이터 구조가 이러한 기능을 가지고 가정 해 봅시다 :

// Gets a data element from the structure. 
void* get(myStruct *x); 
// Prints out all the data elements. 
void print(myStruct *x); 
// Adds an element into the structure. 
void add(myStruct *x, void *to_be_added); 

그것은 그들이 모두 접근이기 때문에 다른 스레드가 print를 호출하는 동안 어떠한 get를 호출 할 수있는 문제가 아니다. 그러나 및 print은 현재 작동 중이며 add은 현재 호출 중입니다. 그 반대의 경우 은 현재 getprint이 진행중인 경우 작동하지 않습니다.

그래서 나는처럼 보이도록 myStruct 변경 다음

typedef struct 
{ 
    void** array_of_elements; 
    size_t size; 

    // True when a mutator is editing this struct. 
    bool mutating; 
    // The number of threads currently accessing this struct. 
    int accessors; 
} myStruct; 

이제 내 기능을 다음과 같이 :

void* get(myStruct *x) 
{ 
    // Wait for mutating to end. 
    while (x->mutating); 
    // Indicate that another accessor is now using this struct. 
    x->accessors++; 

    // get algorithm goes here 

    // Declare we are finished reading. 
    x->accessors--; 

    return ... 
} 

// Same as above... 
void print(myStruct *x) 
... 

void add(myStruct *x) 
{ 
    // Wait for any accessors or mutators to finish. 
    while (x->mutating || x->accessors > 0);  
    x->mutating = true; 

    // add algorithm here 

    x->mutating = false; 
} 

하지만를, 내가 많은 문제가이 함께 있다고 생각 접근 방법을 찾지 못하면 해결 방법을 찾을 수 없습니다.

  • 나의 급우 중 한 명은 나 같은 사용 루프를 사용하여 대단히 느려지라고 말했습니다.
  • 큐 감각이 없습니다. myStruct이 끝나기를 기다리기 시작하는 첫 번째 방법은 반드시 다음에가는 것이 아닙니다.
  • 스레드가 다음에가는 대기열 데이터 구조가있는 경우에도 데이터 구조도 동기화되어야합니다 (). 동기화 자체 데이터 동기화를 필요로하는 무한 루프 자체가입니다.
  • 나는 그것이 뮤 테이터 스레드가 값의보고에 대해 같은 나노에 두 번째 스레드가 0 및 돌연변이 시작입니다 1-0에서 accessors 카운터 (그들은 독서를 시작하려는 의미), 그것은 가능을 변경하는 것이 가능하다고 생각. 그런 다음 뮤 테이터 스레드와 접근 자 스레드가 동시에 진행됩니다.
  • 나는이 논리가 그리드 - 락 (서로를 무한히 기다리는 스레드)을 야기 할 수 있다고 확신한다.
  • 특정 스레드를 잠자기 상태로 만드는 방법을 알지 못하고 루프가 while 루프에 걸리는 것 외에도이 작업을 위해 필요할 때 바로 깨울 수 있습니다.
+0

읽기/쓰기 잠금을 조사하십시오 ... – Dmitri

+0

@Dmitri 실제 구현이 어떻게 될지 원격으로 읽기/쓰기 잠금을 가지고 있지 않습니까? – Hatefiend

+0

스레드간에 변수를 공유하는 경우 원자 접근이나 뮤텍스와 같은 일종의 동기화 메커니즘을 사용해야합니다. 읽기 - 쓰기 잠금은 다중 스레드가 읽을 수 있지만 쓰기를 위해 독점적 인 액세스가 필요하다는 점을 제외하고는 뮤텍스와 같습니다. posix 쓰레드의 경우,'pthread_rwlock_t'가 있습니다. 윈도우에 "슬림 리더 라이터 잠금"이 있습니다. – Dmitri

답변

0

잘못된 생각이 들었을 것입니다. 어떤 OS를 프로그래밍하고 있는지 잘 모르겠습니다 만, 원하는 작업을 수행하기 위해 mutex 또는 semaphore의 개념을보고 싶습니다.준수 POSIX 리눅스/유닉스에

, 당신의 pthreads 볼 수 있습니다 :

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682530(v=vs.85).aspx

:

http://www.cs.wm.edu/wmpthreads.html

는 Windows에서 당신이 mutex 개념에 가까운 무언가를 Critical Sections 볼 수 있습니다

semaphore에 가까운 경우 WaitForMultipleObjects :

https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

그리고 예 : while 루프를 사용하는 것은 좋지 않습니다. 이 경우 사용중인 루프를 사용 중입니다. 여기에 더 많은 읽기 :

What is a busy loop?

mutex 또는 semaphore 사용은 루프가 필요없는 동안. 행운을 빕니다!

+0

구현이 라이브러리에 달려 있습니까? 그건 맞지 않아. 내'struct' 내부에서 생각했는데,'struct' **가 뮤텍스 **이므로 내 스레드를 잠그기 위해 변수를 추가해야합니다. – Hatefiend

+0

다시 말씀 드리겠습니다 : 스레드 라이브러리를 사용하지 않고이 작업을 수행 할 수있는 방법이 있습니까? 내 구조를 사용하는 개발자가 내가 설계 한 운영 체제에 없을 수도 있습니다. 그래서 대신'struct '를 사용하는 것이 안전한지 아닌지를 지정하는'struct' 안에 변수를 넣을 수 있습니까? – Hatefiend

+0

@Hatefiend 특정 스레드 API에 코드를 묶고 싶지 않은 경우 사용자 자신의 일회용 뮤텍스 또는 읽기 - 쓰기 잠금을 구현하는 대신 사용자가 잠금을 해제하는 것이 좋습니다. 기대했던 것보다 정확하게하기가 더 어려워진다.) 그들이 할 필요가있는 모든 것은 자신이 선택한 잠금 장치 (아마도 그들이 사용하고있는 스레딩 구현과 함께 사용되는 잠금 장치)를 획득/릴리스하는 것입니다. – Dmitri