본문 바로가기
공부,일/C# 네트워크

210817 쓰레드

by fromnothing1 2021. 8. 17.

Thread( 쓰레드)   :  실행 중인 (메소드/함수/프로시저)

Process(프로세스) : 실행중인 프로그램 

Process(프로세서) :  CPU

 

Multi process :  자원공유불가 process 간 연결 필요 

Multi Thread : 자원공유가능 ( 자원공유가 문제가 될 수도 있음 -> 동기화 기법 필요)

 

 

c# 쓰레드 예제 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;


namespace _210817_001
{


    class Program
    {
        static void Main(string[] args)
        {
            Thread Lifethread = new Thread(DoStop);

            Lifethread.Start(); // 쓰레드 시작 

            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine("주 스레드 카우터 : {0}", i);
                Thread.Sleep(5);
            }
            Lifethread.Join();
            Console.WriteLine("스레드 종료 ");

            //WorkThread.Join(); // 쓰레드 함수(DoStop)가 종료할때 까지 대기 

        }

        private static void DoStop()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("외부 카우터 : {0}", i);
                Thread.Sleep(5);
            }

        }

    }
}

프로그램간 데이터 전달과 수신 

 

InterProcess  communication (IPC) : 내부 브로세서끼리 통신 

 

PID : 프로세스 번호 

넷 통신을 위해서는 process 마다 port 번호 가 존재한다.

 

visual studio winform 간 데이타 전달

(winform .net 으로 실시)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _210817_004
{
    public partial class Form1 : Form
    {
        static public string SendName = "지옥으로 키티";
        public Form1()
        {
            InitializeComponent();
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;


namespace _210817_003
{
    public partial class Form1 : Form
    {
        bool Runflags = true;
        Thread ReceThred = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void ReceiveData()
        {
            while (Runflags)
            {
                Thread.Sleep(1);
                foreach (var proc in Process.GetProcesses())
                {
                    if (proc.ProcessName.ToString() == "210817_004")
                    {

                        Runflags = false;
                        this.lblResult.Text = _210817_004.Form1.SendName;
                    }
                }
            }
            ReceThred.Abort(); // 쓰레드 강제 종료 ( 쓰레드 가 종료 안되더라고 강제로 종료시킨다.)
        }

        private void btnReceive_Click(object sender, EventArgs e)
        {
            ReceThred = new Thread(ReceiveData);
            ReceThred.Start();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(ReceThred != null)
            {
                ReceThred.Abort(); // form 종료시 강제 종료 
            }
        }
    }
}

위와 같은 winform 2개 생성 

 

receive 하는 form 에서 

지옥으로 키티 전달 라벨을 가진 form 의 실행 파일을 가져온다. 

 

recieve 파일을 먼저 실행해 놓고 button 있는 winform 실행 

-> button 클릭 

크로스 쓰레드 에러  

크로스 쓰레드 에러 발생 ( 디버그 모드로 실행시 )

1부터 textbox 숫자만큼 더하는 쓰레드 프로그램

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;




namespace _210817_005
{
    public partial class Form1 : Form
    {
        Thread SumThread = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SumThread = new Thread(new ParameterizedThreadStart(NumSum));
            SumThread.Start(this.textBox1.Text); //this.textBox1.Text 값을 object n 에 넘겨 줄수 있다.
        }

        private void NumSum(object n)
        {
            long sum = 0;
            long k = Convert.ToInt64(n);

            for (long i = 0; i < k; i++)
            {
                Thread.Sleep(1);
                sum += i;
                this.lblResult.Text = "계산중 ..." + sum.ToString();
            }
            this.lblResult.Text = "계산완료: " + sum.ToString();

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(SumThread !=null)
            {
                SumThread.Abort();
            }
        }
    }
}

델리게이션으로 해결가능

(디버그 해보면 크로스 에러가 뜨지 않는다.)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;




namespace _210817_005
{
    public partial class Form1 : Form
    {
        Thread SumThread = null;
        private delegate void OnResultDelegate(string strText); // 델리게이트 선언
        private OnResultDelegate ResultView = null; // 델리게이션 객체 생성

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            ResultView = new OnResultDelegate(ResultSum); // ResultSum = ResultView 
        }

        private void ResultSum(string NumSum)
        {
            this.lblResult.Text = NumSum;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SumThread = new Thread(new ParameterizedThreadStart(NumSum));
            SumThread.Start(this.textBox1.Text); //this.textBox1.Text 값을 object n 에 넘겨 줄수 있다.
        }

        private void NumSum(object n)
        {
            long sum = 0;
            long k = Convert.ToInt64(n);

            for (long i = 0; i < k; i++)
            {
                Thread.Sleep(1);
                sum += i;
                Invoke(ResultView, "계산중 : " + sum.ToString()); 
                // Invoke(델리게이션객체, 매개변수)
                //main 쓰레드의 자원을 직접 건드리는게 아니라 델리게이션과 invoke 함수를 통해서 간접 적으로 접근

            }
            Invoke(ResultView, "계산 완료 : " + sum.ToString());
            SumThread.Abort();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(SumThread !=null)
            {
                SumThread.Abort();
            }
        }

      
    }
}

델리게이션 사용코드 

 

 

 

 

댓글