fork 를 이용한 filecopy

nuri의 이미지

안녕하세요

fork 를 이용해서 filecopy 를 할려고 합니다.
문자열만 입력된 파일이고 영어 소문자만 들어가 있습니다.

childe process 에는 소문자를 -> 대문자로
parent process 에는 소문자 그대로 output 파일에 내용을 복사
하는 프로그램 입니다.

inputfile 내용이 abcdefg 이면 outputfile 내용은
abCdeFG 이런식으로 출력하는 겁니다.

프로그램에 잼병이라 참 힘드네요
코드를 짜긴 했는데 output 결과가 뒤죽박죽 지 멋대로 나옴니다
ㅠ_ㅠ

#include <stdio.h>

int main()
{
                  
        int old_fd,new_fd,n;

        char *buf;

        old_fd = open("input_file",0);

        new_fd = creat("output_file",0666);

        buf = (char *)malloc(sizeof(char));


        if (fork() == 0) /* Child Process */
        {
                while((n = read(old_fd,&buf,1)) != 0)
                {
                        buf = buf - 'a' + 'A'; 
                        /* 소문자를 대문자로 변환 */
                        write(new_fd,&buf,n);
                        sleep(1);
                }

        } else { /* Parent Process */

                while((n = read(old_fd,&buf,1)) !=0)
                write(new_fd,&buf,n);
                sleep(1); 

        }
        close(old_fd);
        close(new_fd);
}

어떻게 해야 잘 되는지 조언좀 부탁드립니다.

bear의 이미지

위 소스의 경우 이렇게 출력 될것 같은데요.^^;;

확인 해보세요..^^

AaBbCDEcde

이런식으로 두번씩 출력 되지 않을까 합니다..^^;;

무작위로 두번 겹쳐서 나올듯 합니다.^^

그냥 생각으로 적어 보았습니다.^^

컴파일 해보고 다시 올려 볼께요..^^

lock이 없네요..^^

doraq의 이미지

윗분 말씀대로 outputfile 에 두 프로세스가 쓰기 경쟁을 하기 때문에
무작위로 두 출력이 섞여 나오는게 맞습니다.
섞이는 정도는 전혀 예측 안되구요.
출력이 따로 나오는걸 원하시면 각각 outputfile을 열어야 하구요.
한 파일에 순서대로 나와야 한다면 lock을 걸기 이전에 fork를 할 이유가 없어지구요.
일부러 race condition을 보여주려는 목적이 아니라면 좋은 예는 아니네요

nuri의 이미지

안녕하세요
답변 감사 합니다.

race condition이 일어나느것은 짐작하고 있습니다.

제 질문의 의미가 정확히 전달이 안된것 같군요.
질문이 요지는

input file 의 내용을 fork 를 통하여 ouput file 로 복사할때
순서가 뒤바뀌지 않고 결과물이 저장되게 할수 있는
(child process 는 소문자 -> 대문자로)

안전한 방법이 뭐가 있을지 조언을 구하는 것입니다.

sangwoo의 이미지

아직도 요지를 잘 파악하지 못했습니다만 :)
일단 몇가지..
- buf는 pointer to char 이므로, &buf 가 아니고 buf로 써야 할 부분이 있습니다.
- 같은 이유로 *buf = *buf -'a' + 'A'; 로 써야하며, 이것보다는 toupper()를 쓰시는
편이 낫습니다.
- parent에서 write()후 sleep(1)을 하는 것이 목적이라면, write()와 sleep()을
brace로 감싸야 합니다. 아니면 write loop을 돈 후에 sleep(1)은 한번만 실행됩니다.
- 순서를 제대로 나오게 하고 싶다면, read()와 write()가 atomic 하게 실행되어야
합니다. (프로세스 사이의 관점에서) 따라서 read()와 write() 전후에 lock, unlock
루틴을 넣어 주시는게 안전합니다. (세마포어나, 파일을 사용해서 구현하면 됩니다.)

참고로, fork() 된 두 프로세스는 파일의 오프셋을 공유하기 때문에, 몇몇 분이
말씀하신것처럼 aAbB 이런 식으로는 출력되지 않습니다. ;-)

----
Let's shut up and code.

nuri의 이미지

답변 달아 주신분들 감사합니다.

조금더 공부를 해야 겠군요. :D

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.