중복실행방지 방법

dummy999의 이미지

A라는 프로그램을 만들고 이프로그램이 두번실행되지않게하고싶습니다.
그래서 A가 도는와중에 또 A를 실행시키면
A가 돌고있습니다라는 말을 표시한후에 종료하고싶습니다.
이렇게하려면 공유메모리를 쓰면되는데 저는 그쪽 메카니즘은 잘모릅니다.

이부분을 쉽게 C로 구현할수있을까요?

다크슈테펜의 이미지

MUTEX
공유메모리보다는 아마 프로세스 동기화 보시는게 좋을 것 같습니다.
MUTEX로 검색해보시면 아마 예제 많이 나올겁니다.
MFC나 그리고 C#에서도 통용되는 거니까 알아두시면 좋을 것 같습니다.

인생이란게 다 그런게 아니겠어요....? 뭘(?)
http://schutepen.egloos.com

indie의 이미지

간단하게 하시려면
A 프로세스가 실행될때
/tmp밑에 A.pid란 파일을 만들고 자신의 프로세스 아이디를 저장한도록 합니다.
만일 A.pid란 파일에 자신이 아닌 다른 프로세스 아이디가 기록되 있으면
종료합니다.

그냥 단순한 방법입니다. -_-

집에나 갈까?

익명 사용자의 이미지

pid(ProcessID란 의미겠지요?) 파일을 어떻게 만들며 이 형식의 파일에 대해서 좀 더 구체적인 설명 부탁 드리겠습니다.
제가 모르는게 너무 많아가지구 말입니다.
기다리겠습니다...

김정균의 이미지

이 방법의 단점은 race condition이 발생할 수 있다는 점이죠. :-) 물론 실행이 자주 되지 않는 경우라면 크게 문제 없는 경우입니다.

mach의 이미지

* 참고.

* 중복실행방지?
=> 재진입(reentrant)이 방지되게 하는 것입니다.

전형적으로 화장실입니다. 일보는 중에 누가 들어오면 안된다는...
또는 도로의 횡단보도 입니다. 사람이 지나가면 차가가면 안되고 차가 지나가면
사람이 지나가면 안되고...

해결은 ? 플래그지요.
그런데, 이 플래그를 아무나 세우게 하면 누가 진짜인지 헷갈리므로,
강력한 중재자가 세우는것이 대체로 맞습니다. 고로 운영체제가 플래그를 관리하게 합니다.

그래서, 정리하면, 운영체제가 유일한 자원을 경쟁하고 있는 프로세스들로 부터
단 한개에게만 선점하게 한다. 라는 방법이 대두됩니다.
또한, 선점해놓고, 불의의사고로(오류..등) 프로세스가 사망하면, 이를 반납하게 하여, 다른 프로세스가 사용할 수 있게 합니다.

1) 유일한 자원에 대해 reentrant를 방지==>락(lock)을 사용
2) 자원점유 프로세스가 종료시 자원반납 ==> ??
3) 서로다른 프로세스간에 해당 자원에 접근 시도가 가능해야함==>(IPC)

2)를 해결해야 하는데, 프로세스가 죽었을때, 대타가 지속실행되어야 한다면, ....
그래서 영속성(persistence)에 대해 잠시 ...
즉, 커널(운영체제)이 제공하는 IPC의 persistence에 대해 잠시 조사합니다.
* pipe, FIFO, POSIX Mutex, POSIX Conditional variable,
POSIX read/write lock, fcntl record locking, POSIX Memory-based semaphore, TCP/UDP socket, Unix domain socket
===> 프로세스 종료시 커널에게 자동 반납
* POSIX message queue, POSIX named semaphore, POSIX shared memory, System V message queue, System V Semaphore, System V shared memory
===> 프로세스가 종료시에도 자동반납은 안함

위에서 언급했듯이, 프로세스가 불의의 버그로 죽는다는 말도 못하고, 사망시
자원을 자동반납하지 않으면,
수동으로 ipcs, ipcrm등으로 수동반납을 해주어야 이를 반납하게 되고, 또는 커널을 리부팅해야만 반납이 이뤄지면, 자동 재실행등을 구현시 문제가 발생합니다.
그래서 전자인 프로세스 종료시 자원을 커널에게 자동반납하는 IPC중에서 선별할 수 밖에 없습니다.

그래서 구현방법은 많이 있습니다만, 다들 많이 쓰는게, 레코드 락킹입니다.
스티븐스의 UNP Volume 2 Interprocess Communications의 9.7장에서는
record locking을 이용한 프로세스의 중복실행 방지에 대한 예제코드를 보이고 있습니다.

* 단지 pid파일 만을 만들면 아니되옵니다. 9999라는 프로세스가 자기 pid를 써놓고, 불의의 사고로 값을 수정없이 사망하면, 다른 프로세스는 진입이 불가하기 때문입니다.
* 뮤텍스도 좋은 방법이지만, POSIX Mutex를 지원하는 시스템을 고려해야 합니다.
* record locking을 권장합니다. 스티븐스님의 코드를 참고하세요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

까막의 이미지

/tmp/aaa.pid 에 process id를 기록해 두고, 해당하는 pid의 프로세스가 있는지 확인한 다음 없으면 /tmp/aaa.pid를 업데이트 하고 실행되면 될 듯 합니다.

Crow's Maniacal World.
http://crowmania.cafe24.com

Let's be engineers!

익명 사용자의 이미지

C보다는 sh로...

참고는 /etc/rc.d/init.d안의 sh script를 참조하시면 될듯...

----오만한 리눅서----

익명 사용자의 이미지

까막 wrote:
/tmp/aaa.pid 에 process id를 기록해 두고, 해당하는 pid의 프로세스가 있는지 확인한 다음 없으면 /tmp/aaa.pid를 업데이트 하고 실행되면 될 듯 합니다.

* 고려사항이 있습니다.
시나리오) PID만 검사하는 경우
1) X 프로세스가 있었다.
2) X 프로세스가 죽었다.
3) 제 3의 프로세스가 X라는 pid로 동작했다.
4) 이때, 새로운 X프로세스가 시작하려했다.

시나리오) PID와 파일명을 검사하는 경우
1) X 프로세스가 있었다.
2) X 프로세스가 죽었다.
3) 제 3의 프로세스가 X라는 pid로 동작했다. 그런데, 우연히도 실행파일명이 동일했다.
4) 이때, 새로운 X프로세스가 시작하려했다.

* 감상: 완벽을 위해 고려할 것이 좀~ 많아지는 군요.
* 그럴 경우 없다라고 한다면 .... 쿵~

까막의 이미지

Quote:

시나리오) PID와 파일명을 검사하는 경우

를 가정하지요.

Quote:

3) 제 3의 프로세스가 X라는 pid로 동작했다. 그런데, 우연히도 실행파일명이 동일했다.

Fullpath check를 해버리면 될 듯 합니다. :)
여러모로 귀찮은 짓이군요.. win32에선 그냥 CreateMutex로 해결했다는;;;

Crow's Maniacal World.
http://crowmania.cafe24.com

Let's be engineers!

bejoy4him의 이미지

mach wrote:

그래서 구현방법은 많이 있습니다만, 다들 많이 쓰는게, 레코드 락킹입니다.
스티븐스의 UNP Volume 2 Interprocess Communications의 9.7장에서는
record locking을 이용한 프로세스의 중복실행 방지에 대한 예제코드를 보이고 있습니다.
...........
* record locking을 권장합니다. 스티븐스님의 코드를 참고하세요.

중복실행 방지법에는 뮤텍스가 가장 무난하고 많이 사용되는 방법인줄 알았는데.. 레코드락이는게 있군요...

처음 들어보는 거네요. 스티븐슨 님의 책을 소개시켜주셨는데. 염치불구하고 레코드 락이라는게 어떤건지 설명 부탁드립니다. 구체적으로 레코드라는게 뭘 말하는건지가 궁금해요.. OS에서 제공하는 IPC같은걸로 이해되는데.. 들어보지 못한 IPC같아서요...

익명 사용자의 이미지

* Record lock이란?
file에 대해 lock을 거는 방법은 누구나 생각할 수 있듯이,
1) 파일 전체에 lock을 건다.
-lockf(), flock() 참조
2) 파일의 일부에 lock을 건다.
- fcntl() 참조

이정도이겠지요.
이때 파일의 특정 부분에 lock을 거는 것을 record lock이라고
합니다. 뭐하는데 쓰냐고요? DBMS 만들때 주로 쓰겠지요.
만일 record lock을 쓴다면 granularity가 높아서 동시에 파일에
접근(특히, exclusive)할 수 있는 프로세스(또는, 쓰레드)의 수가
증가되므로, 성능에 좋은 기대를 할 수 있겠습니다.

* 구체적인 레코드란, 응용프로그래머가 지정한 파일의 지정한 옵셋으로 부터
지정한 길이가 되겠습니다. lseek()으로 파일 커서(파일포인터)를 이동하는
메카니즘과 유사합니다. 특정 파일위치 어디부터 어디까지가 되겠지요.
DB를 만든다면, 아마도 고정크기(가변크기도 가능하겠지만)를 프로그래머가
지정하여 레코드를 생성하겠지요.
- 참고로, APUE - 스티븐스 책의 16장 A database library에서는 레코드 락을
이용한 간단한 데이터베이스라이브러리를 선보이고 있습니다. 성능테스트도 보이고...
물론, berkeley db등과는 기능면에서 많은 차이가 있습니다만......

* OS가 제공하는 IPC는 다양합니다. 그중 record lock은 파일시스템을 통한 ipc라고
볼 수 있겠지요.

dummy999의 이미지

제가 아는 방법으로는 공유메모리를 만들고 그곳에 프로그램의 고유문자열을 넣습니다. (개발자가 지정하지만)
그리고 그프로그램은 시작시 반드시 공유메모리에서 해당위치의 문자열을 확인합니다. 있으면 종료되죠..

어디선가 봤는데 로직은 정말 간단했습니다
그런데 공유메모리부분을 가려놔서 그부분을 어떻게 했는지 모릅니다.
물론 위에 분들이 말한데로 저런거를 연구해봐야겠지만..

첨보는것들이라..
함수들의 기능에대한 개략적인 설명이 없이는 잘모르겠습니다.
물론 man을치면나오겠지만.. 워낙 추상적인 단어들을 모아둔지라..
무슨뜻으로 글을써놓은건지 잘몰겠더라구요..

IPC라는 그런개념에대해 말했는데..
워낙오래전이라 이게 무슨뜻인지도 ^^;

간단하게 함수를 이용해서 예제를 만들고 그것을 설명 부탁드려도될까요?
또 그개념도 부탁드립니다.

------------------------------------
F/OSS bless you... ^^*

익명 사용자의 이미지

dummy999 wrote:
제가 아는 방법으로는 공유메모리를 만들고 그곳에 프로그램의 고유문자열을 넣습니다. (개발자가 지정하지만)
그리고 그프로그램은 시작시 반드시 공유메모리에서 해당위치의 문자열을 확인합니다. 있으면 종료되죠..

어디선가 봤는데 로직은 정말 간단했습니다
그런데 공유메모리부분을 가려놔서 그부분을 어떻게 했는지 모릅니다.
물론 위에 분들이 말한데로 저런거를 연구해봐야겠지만..

첨보는것들이라..
함수들의 기능에대한 개략적인 설명이 없이는 잘모르겠습니다.
물론 man을치면나오겠지만.. 워낙 추상적인 단어들을 모아둔지라..
무슨뜻으로 글을써놓은건지 잘몰겠더라구요..

IPC라는 그런개념에대해 말했는데..
워낙오래전이라 이게 무슨뜻인지도 ^^;

간단하게 함수를 이용해서 예제를 만들고 그것을 설명 부탁드려도될까요?
또 그개념도 부탁드립니다.

회 좋아하십니까?

galien의 이미지

무단포옹 wrote:
dummy999 wrote:
제가 아는 방법으로는 공유메모리를 만들고 그곳에 프로그램의 고유문자열을 넣습니다. (개발자가 지정하지만)
그리고 그프로그램은 시작시 반드시 공유메모리에서 해당위치의 문자열을 확인합니다. 있으면 종료되죠..

어디선가 봤는데 로직은 정말 간단했습니다
그런데 공유메모리부분을 가려놔서 그부분을 어떻게 했는지 모릅니다.
물론 위에 분들이 말한데로 저런거를 연구해봐야겠지만..

첨보는것들이라..
함수들의 기능에대한 개략적인 설명이 없이는 잘모르겠습니다.
물론 man을치면나오겠지만.. 워낙 추상적인 단어들을 모아둔지라..
무슨뜻으로 글을써놓은건지 잘몰겠더라구요..

IPC라는 그런개념에대해 말했는데..
워낙오래전이라 이게 무슨뜻인지도 ^^;

간단하게 함수를 이용해서 예제를 만들고 그것을 설명 부탁드려도될까요?
또 그개념도 부탁드립니다.

회 좋아하십니까?

이해도 하고 동의도 하지만, 너무 강력하신거 아닙니까....
:wink:
(저도 가끔회를 즐깁니다.)

dummy999의 이미지

김상욱 wrote:
무단포옹 wrote:
dummy999 wrote:
제가 아는 방법으로는 공유메모리를 만들고 그곳에 프로그램의 고유문자열을 넣습니다. (개발자가 지정하지만)
그리고 그프로그램은 시작시 반드시 공유메모리에서 해당위치의 문자열을 확인합니다. 있으면 종료되죠..

어디선가 봤는데 로직은 정말 간단했습니다
그런데 공유메모리부분을 가려놔서 그부분을 어떻게 했는지 모릅니다.
물론 위에 분들이 말한데로 저런거를 연구해봐야겠지만..

첨보는것들이라..
함수들의 기능에대한 개략적인 설명이 없이는 잘모르겠습니다.
물론 man을치면나오겠지만.. 워낙 추상적인 단어들을 모아둔지라..
무슨뜻으로 글을써놓은건지 잘몰겠더라구요..

IPC라는 그런개념에대해 말했는데..
워낙오래전이라 이게 무슨뜻인지도 ^^;

간단하게 함수를 이용해서 예제를 만들고 그것을 설명 부탁드려도될까요?
또 그개념도 부탁드립니다.

회 좋아하십니까?

이해도 하고 동의도 하지만, 너무 강력하신거 아닙니까....
:wink:
(저도 가끔회를 즐깁니다.)

다만제가 알고싶은것은 개념적인부분이아니라.
매커니즘면에서 어떤식으로 구현되고있는지 알고싶다는겁니다.

알고보니 저도 회를 좋아라했었더군요.. :D

------------------------------------
F/OSS bless you... ^^*

익명 사용자의 이미지

공유메모리에 특정 태그(문자열)을 사용하여 락을 거는 방법은
최초 그 문자열을 생성한 프로세스가 불의의 사고로, 공유메모리에 대한 처리(제거) 없이
사망한 경우, 이후에 새로이 생성되는 프로세스가 자신이 최초인지?(실행되어야 하는지?)
를 판단하는데, 헷갈릴수 있으므로(단순로직으로 했다면, 이미 이전 프로그램이 수행중인것으로 오판하고...) ... 이를 위한 로직이 또 필요하고... 아 귀찮다~.
하여간, 이 경우라면, 공유메모리를 권하고 싶지 않습니다.

* 유닉스/리눅스계열이고, 호환성이 필요하다면, record locking이 가장 좋다고
생각합니다.(당연히, 개인 취향이지요...) 사례는(함수) 스티븐스 책에 있고...

* 윈도우에서는 www.codeproject.com에 가서 찾아보시면, 디자인패턴의
singleton패턴에 입각한 예제들이 몇개 있습니다만.... (과거 윈도우 프로그램 잠시.. 할때, 실제 적용해봐도 잘 되더군요..) 키워드라면, single instance정도겠네요.

회에다 x주를 곁들이면 더 좋을듯합니다. 비... 오니 더 생각나는군요.

익명 사용자의 이미지

숙제는 스스로 해야...

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.