하나의 서비스에서 여러 프로세스를 관리할 수 있나요.

산업용 장비 통신 인터페이스 서비스를 개발하고 있습니다.
장비 컨트롤러에서 제공하는 통신 DLL을 C#으로 래핑할 때 모두 static으로 구현해야해서 그런지 서비스 내부에서 멀티 스레드 동작이 되지 않고 있습니다. (정확하게 파악된건지는 아직 모르겠습니다.)

서비스의 목적이 장비 내부 데이터를 가져와 데이터베이스에 주기적으로 저장하는 것인데, 현재는 데이터 저장 주기가 너무 느립니다.

하여 다른 대안으로 멀티스레드가 아닌 멀티프로세스로 구현을 고민하고 있습니다.
좋은 방법인지는 모르겠으나 여러 장비를 그룹으로 나눠(100대면 10대씩 10그룹으로…) 그룹별로 프로세스를 구분하려고 합니다.

여기에서 문의드리고자 하는 건 하나의 윈도우 서비스에 여러 프로세스를 구분할 수 있도록 프로그램을 할 수 있는지… 가능하다면 어떤 키워드나 라이브러리 등을 참고할 수 있는지를 여쭙습니다.

감사합니다.

3개의 좋아요
  • API가 static이라고 해서 멀티 스레드 동작이 안되는 것은 아닐 것 같습니다.
    • 제공하는 API가 여러 스레드에서 동시 호출이 되는지 (스레드 세이프한지) 를 살펴보시면 될 듯 합니다.
  • 윈도우 서비스가 시작할 때 실행파일을 실행하면 됩니다. (Process.Start())를 통해 여러 프로세스를 적절한 인자를 전달하여 실행하면 됩니다.
  • 실행 권한은 살펴보셔야 하는데 윈도우 서비스가 실행파일을 실행할 수 있는 권한이 있어야 합니다.
  • 생성된 여러 프로세스가 잘 동작하는지 HeartBeat할 필요가 있습니다.
  • 서비스 종료 시 생성된 프로세스들을 정상 종료 및 강제 종료해야 할 수 있습니다.
  • 프로세스와의 통신은 Console I/O를 이용하거나 익명 파이프를 이용할 수 있습니다.
    방법: 로컬 프로세스 간 통신에 익명 파이프 사용 - .NET | Microsoft Learn
3개의 좋아요

문제의 원인부터 정확히 파악하고 대안을 찾으세요

1개의 좋아요

GPT 4.0 내용 참고해보시기 바랍니다.
윈도우 서비스에서 멀티프로세스를 사용하는 방법에 대해 답변드리겠습니다.

윈도우 서비스에서 여러 프로세스를 생성하는 것은 가능합니다. 윈도우 서비스가 시작될 때 ServiceBaseOnStart 메서드에서 각 프로세스를 시작하면 됩니다.

다만 주의해야할 점은 각 프로세스가 제대로 종료되도록 관리해야 합니다. 서비스가 중지될 때 ServiceBaseOnStop 메서드에서 각 프로세스를 제대로 종료해야 합니다.

예제 코드는 다음과 같습니다:

using System.ServiceProcess;
using System.Diagnostics;

public class MyService : ServiceBase
{
    private Process _process;

    public MyService()
    {
        this.ServiceName = "MyMultiProcessService";
    }

    protected override void OnStart(string[] args)
    {
        StartProcess();
    }

    protected override void OnStop()
    {
        StopProcess();
    }

    private void StartProcess()
    {
        ProcessStartInfo psi = new ProcessStartInfo("C:\\path\\to\\yourapp.exe");
        _process = new Process();
        _process.StartInfo = psi;
        _process.Start();
    }

    private void StopProcess()
    {
        if (_process != null && !_process.HasExited)
        {
            _process.Kill();
            _process.WaitForExit();
        }
    }

    public static void Main()
    {
        ServiceBase.Run(new MyService());
    }
}

다만, 이 방식으로 여러 프로세스를 생성하면 서비스의 관리와 유지보수가 복잡해질 수 있습니다. 따라서 여러 프로세스를 사용하는 것보다는 문제의 원인을 파악하고 해결하는 것이 더 바람직합니다.

DLL과 관련된 멀티스레딩 문제를 해결하는 몇 가지 방법은 다음과 같습니다:

  1. 동기화: Mutex, Semaphore, Lock 등의 동기화 메커니즘을 사용하여 특정 부분 코드가 한 번에 하나의 스레드에서만 실행되도록 합니다.
  2. 스레드 풀: ThreadPool을 사용하여 작업을 관리하고, 제한된 수의 스레드에서 동시에 작업을 처리합니다.
  3. 개선된 라이브러리 사용: 특정 DLL의 스레드 안정성 문제가 있다면 해당 DLL의 업데이트된 버전을 찾거나, 다른 라이브러리를 찾아볼 수 있습니다.

마지막으로, 멀티프로세스로 구현을 고려하기 전에 DLL의 문서나 제공자에게 멀티스레드 환경에서 안정적으로 사용할 수 있는지 여부를 확인하는 것이 좋습니다.

3개의 좋아요

=> DllImport 하는것을 말하는건가요? static과 상관없이 멀티쓰레드 지원할 수 있습니다.

DLL 내부에서 멀티쓰레드를 지원하는지 알아보는게 첫번째인거 같습니다.
만약 DLL 내부에서 함수마다 전역 뮤텍스 변수를 락/언락 하는거면 쓰레드 써봐야 소용없습니다.
멀티쓰레드를 지원한다면 DLL 함수에 컨텍스트에 해당하는 id 같은 변수를 전달받을거같긴한데 함수의 용도에 따라 필요없을수도 있습니다.

2개의 좋아요

자세한 답변 감사드립니다.
static이어도 멀티스레드가 될 수 있는 부분은 참고하겠습니다.
현재는 제대로 동작이 안되는 부분은 마지막 언급하신 부분이 아닐까 합니다.

2개의 좋아요

제가 봐서는 윈폼 베이스에서 작업하시는거 같은데…
dll을 랩핑해서 쓰신다는 부분이나 멀티스레드 처리하시는 부분들에 대해서
소스코드라도 있으면 도움이 좀 될 것 같습니다.
Multi thread를 제대로 구현 안 해놓으셨을 수도 있습니다.

2개의 좋아요