리눅스에서 공유 메모리 API를 사용합니다. 하나의 쓰기 (A 프로세스)와 하나의 읽기 (B 프로세스) 만 있으면 세마포어가 필요합니다. 세마포어없이 공유 메모리를 사용하면 리눅스에서 교착 상태가 발생한다는 예제가 있습니다.세마포어가없는 공유 메모리 액세스
답변
세마포어 (또는 더 일반적으로 MUTEX)가 없으면 교착 상태가 발생할 수 없습니다. 그러나 일어날 수있는 일은 모순 된/일관되지 않은 데이터입니다.
예를 들어, 공유 메모리 위치에서 발견 된 오브젝트 유형이 텍스트 문자열을 나타내는 char 배열 인 경우. 한 스레드가 문자열을 수정하고 다른 스레드가 한 번 읽으므로 홀수 메시지를받을 수 있습니다.
For example: Original text "The British are coming!" Thread 1 start changing to "Warn all patriots!" but only gets to write the first 8 characters. Then... Thread 2 reads "Warn allish are coming!
편집 : 일반적으로 하나의 메아리, 포인터 및되어 정의 관련 개념에 제공 Falaina의 반응 참조 : 하나의 프로세스 만하면 우승 기록과 함께 경쟁 조건, 자성, 뮤텍스를 ...
를 ' 교착 상태에 빠질 수는 없습니다.
그러나 독자는 읽을 때 부분적으로 쓰여진 데이터를 처리 할 수 있어야합니다. 그리고 그것은 불가능할 수도 있습니다.
또한 하나의 글을 쓰고 하나의 글을 읽고 있다고 말하면 읽기 전용을 의미합니까? 한 프로세스가 파이프에 물건을 넣고 다른 파이프가 파이프에서 물건을 제거하는 파이프를 의미한다면, 정말로 두 사람 모두 공유 메모리에 쓰고 있습니다.
공유 메모리에 액세스 할 때 (읽기만하지 않는 한) 동시 쓰기 또는 쓰기 중 읽기를 방지해야합니다. 적절한 방법은 세마포어를 사용하는 것입니다.
이 ScopedLock 클래스를 잠금 메커니즘으로 사용할 수 있으며 한 프로세스 만 특정 이름의 범위가 지정된 잠금을 동시에 소유 할 수 있습니다. 다른 프로세스가 프로세스를 작성하려고 시도하면 첫 번째 프로세스 범위 잠금이 범위를 벗어날 때까지 프로세스가 차단됩니다.
#include <semaphore.h>
class ScopedLock{
sem_t *sem;
public:
ScopedLock(const char* name) : sem(0)
{
sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, 1);
if (sem == SEM_FAILED)
{
printf("Error opening semaphore : %s\n", last_error_message());
throw "failed to create semaphore";
}
printf("locking interprocess lock...\n");
if (-1 == sem_wait(sem))
{
printf("Error locking semaphore : %s\n", last_error_message());
throw "failed to lock semaphore";
}
printf("interprocess lock locked\n");
}
~ScopedLock()
{
if (sem)
{
sem_post(sem);
printf("interprocess lock unlocked\n");
}
}
// static destroy function, use for cleanup
static void destroy(const char *name)
{
sem_t *sem = sem_open(name, O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (sem != SEM_FAILED)
{
sem_post(sem);
sem_destroy(sem);
}
if (-1 == sem_unlink(name))
{
printf("Error destroying semphore: %s\n", last_error_message());
}
}
};
그 시점에서 뮤텍스 구현이되지 않습니까? –
귀하의 질문은 약간 이상합니다. 우선 동기화의 다른 방법이 있기 때문에 세마포어를 사용할 필요가 없습니다.
둘째, 어떤 이유로 세마포어가 잠금 또는 다른 동기화 방법을 보호하지 않았다면 세마포어를 사용하면 교착 상태가 발생하지 않습니다. 동기화 방법을 사용하면 교착 상태가 발생하는 경향이 있습니다. 이것은 할 수 있습니다 : 당신이 작가 (들)와 같은 자원에 대한 경쟁 독자 (들)이있을 때
그러나, 한 작가와 한 독자의 질문에 대한 지금 Race Condition
으로 알려진 수 있습니다 세마포어 또는 다른 수의 동기화 메소드 대신 뮤텍스를 사용하여 수행됩니다. 또는 B 프로세스의 쓰기가 원자적임을 보장 할 수 있다면 (즉, 인터럽트되면 공유 메모리를 일관성없는 상태로 둘 수 없음), 동기화가 필요하지 않습니다. 후자의 시나리오는 공유 메모리가 단일 명령어로 업데이트 될 수없는 경우 (때로는 충분하지 않은 경우도 있음) 매우 드뭅니다. 안전 경로를 사용하고 공유 메모리에 대한 액세스를 잠그는 것이 좋습니다.
모든 의견을 보내 주셔서 감사합니다. struct sharedStruct {bool isOk; }; 필자는 while 루프에서 (isOK)와 다른 프로세스 (isOK)를 읽으려는 프로세스가 하나씩 있다고 생각합니다. 읽는 동안 변수의 상태 (true 또는 false)에 관계없이 정상적으로 작동합니다. 심지어 프로세스 B (isOK 작성)의 여러 사본을 실행하고 아무런 문제도 볼 수 없습니다. 이상한 행동을 방지하기 위해 어떤 추가 코드가 필요한지 이해하고 싶습니다. (경쟁 조건 등) 그리고 그 이상한 상태로 들어가는 법. –
읽기/쓰기 메소드가 모두 동일한 객체/스트림에서 작동합니까? Process A/Process B의 여러 인스턴스가 동시에 실행될 수 있습니까? –