Arch Linux에서 경쟁 조건이 작동하지 않습니다.

Arch Linux에서 경쟁 조건이 작동하지 않습니다.

다음 C 프로그램은 하위 프로세스와 상위 프로세스 간의 경쟁 조건을 설명하는 것으로 간주됩니다.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
     fork();
     printf("\n 1234567890 \n");
     return 0;
}

내 친구들이 그것을 실행할 때 (on우분투), 그들은 예상된 출력을 얻습니다. 이는 뒤죽박죽된 1234567890s입니다.

한 가지 예:12312345645678907890

하지만 내 컴퓨터에서 같은 프로그램을 사용해 보면아치 리눅스, 결코 그러한 출력을 제공하지 않습니다. 그것은 항상 차례로입니다.

 1234567890 

 1234567890 

나는 그것을 좋아한다아치 리눅스경쟁 조건을 피하는 방법은 있지만장애를 입히다그러한 기능이 있으며 내 친구의 것과 같은 결과를 얻고 싶습니다.

답변1

호출 printf은 하나 이상의 write(2)시스템 호출을 실행하며 처리되는 순서는 출력의 실제 순서입니다. C 라이브러리 내부의 버퍼링에 따라 달라지므로 하나 이상입니다. 라인 버퍼 출력(터미널로 이동)을 사용하면 write초기 개행에 대해 한 번, 나머지에 대해 한 번, 두 번의 호출을 받을 가능성이 높습니다.

write(1, "\n", 1);
write(1, " 1234567890 \n", 13);

호출 사이에 다른 프로세스를 예약하여 먼저 두 개의 빈 줄을 제공하고 그 다음에는 숫자가 있는 줄을 제공할 수 있지만 처리가 많이 진행되지 않는다는 점을 고려하면 언로드된 시스템에서는 그럴 가능성이 없습니다.

두 프로세스 모두 정확히 동일한 내용을 인쇄하므로 하나가 다른 프로세스를 방해하지 않는 한 어느 프로세스가 먼저 진행되는지는 중요하지 않습니다.

출력이 파일이나 파이프로 이동하는 경우 기본값은 완전히 버퍼링되는 것이므로 write프로세스당 한 번의 호출만 얻을 수 있으며 혼합 출력이 발생할 가능성은 없습니다.

개별 시스템 호출을 통해 숫자가 하나씩 출력되는 경우 혼합 숫자의 예가 가능합니다. 길이가 알려진 정적 문자열을 인쇄할 때 합리적인 라이브러리 구현이 왜 그렇게 하는지 이해하기 어렵습니다. 루프에 더 많은 쓰기를 수행하면 혼합된 출력이 발생할 가능성이 더 높아집니다.

이 같은:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
     int i;
     setbuf(stdout, NULL);  /* explicitly unbuffered */
     int x = fork(); 
     for (i = 0 ; i < 500 ; i++) {
          printf("%d", !!x);
     }
     if (x) {
          wait(NULL);  
          printf("\n");  
     }  
     return 0;  
}

아래와 같이 출력됩니다. 대부분의 경우 항상 그런 것은 아닙니다. 프로세스를 예약하는 방법을 결정하는 것은 시스템에 달려 있습니다. 예측 불가능성 때문에 우리는 일반적으로 경쟁 조건을 피하려고 노력합니다.

111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111
111100000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000010000001001100
110000000011001100110011000000010011001100110000000100110011001100000001001
100110011000000010011001100110000000100110011001100000001001100110011000000
...

답변2

내 의심은 fork()시스템 호출이 다른 프로세스가 호출을 끝내고 printf()자체 프로세스에 도달하기 전에 문자열이 출력에 표시되도록 할 수 있을 만큼 오랫동안 부모 또는 자식 프로세스를 보류하고 있다는 것입니다 printf().

루프에서 많은 수의 문자열을 출력하면 부모 프로세스와 자식 프로세스 모두 동시에 루프를 실행할 시간이 있는 경우 설명하는 혼합 출력이 표시될 수 있습니다.

이 문제를 "수정"하려면 fork()시스템 호출이나 이와 관련된 커널의 구성 요소를 다시 작성해야 할 수 있습니다.

관련 정보