UNIX 휴대용 원자 작동
pthread가 있는 휴대용 스레드와 유사한 원자 변수 연산을 위한 (POSIX-) 휴대용 방법이 C에 있습니까?
원자 연산은 원자적으로 실행되는 "증가 및 증가"와 같은 연산으로, 어떤 컨텍스트 스위치도 연산을 방해할 수 없음을 의미합니다.리눅스 커널 공간에서는 atomic_t를 입력해야 하고 자바에서는 java.util.concurrent.atomic 패키지를 사용합니다.
리눅스에서 atomic.h 파일은 atomic 연산을 제공하지만 include는 플랫폼에 의존적입니다.#include <asm-x86_64/atomic.h>
맥 OS X에서도 비슷한 방식으로 사용할 수 없습니다.
C11 현재 원자 작동을 제공하는 선택적인 원자 라이브러리가 있습니다.이것은 이 옵션 기능이 있는 C11 컴파일러(예: gcc-4.9)가 있는 모든 플랫폼에서 휴대할 수 있습니다.
원자의 존재는 다음과 같이 확인할 수 있습니다.__STDC_NO_ATOMICS__
그리고 의 존재.<stdatomic.h>
원자력의
#include <stdio.h>
#include <stdlib.h>
#ifndef __STDC_NO_ATOMICS__
#include <stdatomic.h>
#endif
int main(int argc, char**argv) {
_Atomic int a;
atomic_init(&a, 42);
atomic_store(&a, 5);
int b = atomic_load(&a);
printf("b = %i\n", b);
return EXIT_SUCCESS;
}
컴파일러 호출
clang -std=c11 atomic.c
gcc -std=c11 atomic.c
미래에 이 문제에 발을 헛디딘 사람들에게, C11 원자학은 지금 이것을 하는 가장 좋은 방법입니다 - 저는 그것들이 GCC 4.9에 포함될 것이라고 믿습니다.
OS X를 요청하신 이후로:
(그리고 이 스레드에서 크로스 플랫폼이 제기되었기 때문입니다.)
OS X에는 OS TomicAdd32()와 친구 기능이 있습니다.이들은 "/usr/include/libkern/OSAtomic"으로 선언됩니다.h). "원자 연산 사용" 섹션의 스레드 프로그래밍 가이드를 참조하십시오.
그리고 Windows의 경우 Interlocked가 있습니다.증분() 및 친구(MSDN 참조).
gcc 내장 __sync_fetch_and_add() 및 친구들(위 링크됨)과 함께 모든 메인 데스크톱 플랫폼을 위한 무언가를 가지고 있어야 합니다.
아직 혼자 사용하지는 않았지만, 앞으로 며칠 안에 사용할 수 있을 것입니다.
아니요, POSIX는 휴대용 잠금/원자 작동을 지정하지 않습니다.그래서 그들은 p실을 가지고 있습니다.
비표준적인 방법을 사용하거나 휴대성을 위해 ptrhead를 고수해야 합니다.
C11 원자학 최소 실행 가능 예
glibc 2.28에 스레드를 추가하면 순수한 C11에서 원자학과 스레드를 모두 할 수 있습니다.
예: https://en.cppreference.com/w/c/language/atomic
본전의
#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>
atomic_int acnt;
int cnt;
int f(void* thr_data)
{
for(int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
// for this example, relaxed memory order is sufficient, e.g.
// atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
}
return 0;
}
int main(void)
{
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
}
컴파일 및 실행:
gcc -std=c11 main.c -pthread
./a.out
가능한 출력:
The atomic counter is 10000
The non-atomic counter is 8644
비원자 카운터는 비원자 변수에 대한 스레드 간의 레이시 액세스로 인해 원자 카운터보다 작을 가능성이 매우 높습니다.
스레드 예제는 다음에서 찾을 수 있습니다: 평이한 C에서 스레드를 시작하려면 어떻게 해야 합니까?
소스에서 glibc를 컴파일하여 우분투 18.04 (glibc 2.27)에서 테스트:단일 호스트 Ubuntu 18.10에 있는 여러 glibc 라이브러리에는 glibc 2.28이 있으므로 거기서만 작동해야 합니다.
AFAIK는 원자 연산을 할 수 있는 크로스 플랫폼 방식이 없습니다.밖에 도서관이 있을지도 모르지만 저는 모릅니다.하지만 직접 굴리는 것은 특별히 어렵지 않습니다.
없는 것 같아요.
이를 해결하는 한 가지 방법 중 하나는 당연히 라이선스가 허락한다면 리눅스 커널 공간에서 아키텍처별로 관련 구현을 복사하는 것입니다.저는 그러한 프리미티브의 진화를 자세히 따라가지는 않았지만, 커널의 다른 서비스나 API에 의존하지 않는 것과 같은, 정말로 프리미티브라고 추측할 수 있습니다.
언급URL : https://stackoverflow.com/questions/1130018/unix-portable-atomic-operations
'source' 카테고리의 다른 글
일반 스왑 매크로를 C에 구현 (0) | 2023.10.03 |
---|---|
MySQL에 decimal을 저장하는 방법은? (0) | 2023.10.03 |
많은 하위 디렉터리를 별도의 새로운 Git 저장소로 분리 (0) | 2023.09.28 |
PowerShell 오류 메시지에서 touch 명령으로 새 파일 만들기 (0) | 2023.09.28 |
jQuery UI 대화상자에서 첫번째 텍스트 상자에 포커스를 설정하지 못하도록 합니다. (0) | 2023.09.28 |