<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bread_code.log</title>
        <link>https://velog.io/</link>
        <description>빵먹으면서 코딩하는 개발자를 꿈꾸는 코린이</description>
        <lastBuildDate>Mon, 24 Jun 2024 08:06:25 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>bread_code.log</title>
            <url>https://velog.velcdn.com/images/bread_code/profile/6338d29b-27b7-4e4f-a256-05b8f584288b/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. bread_code.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/bread_code" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[오즈코딩스쿨] 초격자 캠프 백엔드 코스 후기]]></title>
            <link>https://velog.io/@bread_code/%EC%98%A4%EC%A6%88%EC%BD%94%EB%94%A9%EC%8A%A4%EC%BF%A8-%EC%B4%88%EA%B2%A9%EC%9E%90-%EC%BA%A0%ED%94%84-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@bread_code/%EC%98%A4%EC%A6%88%EC%BD%94%EB%94%A9%EC%8A%A4%EC%BF%A8-%EC%B4%88%EA%B2%A9%EC%9E%90-%EC%BA%A0%ED%94%84-%EB%B0%B1%EC%97%94%EB%93%9C-%EC%BD%94%EC%8A%A4-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Mon, 24 Jun 2024 08:06:25 GMT</pubDate>
            <description><![CDATA[<p>안녕하세요 ㅎㅎ 오즈코딩스쿨 초격자 캠프 백엔드 2기 수료생이 된 공대생이였던  이현아라고 합니다 !.!</p>
<h3 id="오즈코딩스쿨-참여하게-된-계기-👩💻">오즈코딩스쿨 참여하게 된 계기 👩‍💻</h3>
<p>저는 졸업을 앞두고 진로에대해 고민이 많아져 이것저것 보다가 부트캠프 광고들을 보게 되었습니다 ! 예전에 아주 짧게 파이썬으로 코딩을 하는 15일 챌린지같은 것을 해본 적이 있었는데 좀 더 배워보고 싶다는 생각이 들어 부트캠프에 대해 이것저것 알아보기 시작했습니다 -!
그러다가 오즈의 코딩스쿨이 눈에 자꾸 들어왔고 적은 인원인 <strong>30명정도로 하는 소수정예 교육방식, 6개월안에 잘 짜여진 커리큘럼, 그리고 강사분들의 경력이 나와있어서 신뢰가 갔고</strong> 
신청 후 참여 하게 되었습니다 ㅎㅎ</p>
<h3 id="비전공자의-코딩-뿌시기나도-같이-뿌서짐-😵💫">비전공자의 코딩 뿌시기..나도 같이 뿌서짐 😵‍💫</h3>
<p>그러나. 처음엔 무턱대고 비전공이였던 분야에 덤벼서 후뚜루 맞았습니다! 헣허 처음엔 스트레스도 많이 받고 머리에도 잘 안들어오더군요 ㅎㅎ 
혹시 부트캠프를 들으려는 비전공자이신 분이시라면 부트캠프 교육 시작 전 기간에 유튜브 무료강의 등으로 먼저 혼자 코딩해보는 것 추천드립니다 !!</p>
<p>6개월동안 코딩교육을 들으면서 처음엔 쉽지 않았지만 처음 접하는 것이라 어쩔 수 없는 것이니 !! 
온라인 교육이지만 <strong>실시간으로 ZEP이라는 멀티버스 공간에서 조교님들이 계속 제가 하고 있는 화면을 보고 관리해 주시고ㅎㅎ</strong> 잘 되고 있는지 물어봐 주셔서 좋았습니다 ㅎㅎ 모르는 부분은 계속 조교님들께 질문하면서(조교님 괴롭히기) 강의, 실습을 하나씩 뿌셔갔습니닷</p>
<p>처음엔 외계어를 보는 것 같았고..오류들을 많이 만나게 되어 머리가 펑펑 이였지만
오류를 수정하면서 실력이 많이 늘게 된 것 같습니다 !! 
그래도 오류는 머리아프지만😩
<img src="https://velog.velcdn.com/images/bread_code/post/5ab8b960-3004-4d8f-9cd7-9360044c8fc0/image.jpg" alt=""></p>
<h3 id="초격자-캠프를-통해-✏️">초격자 캠프를 통해 ✏️</h3>
<p>오즈코딩스쿨 백엔드 코스과정을 들으면서 
python, django, flask, database, gitub, html, css등에 대해 다뤄 볼 수 있게 되었습니다 !! *<em>언어들에 대해 기초를 배우고, 실습과제를 통해 경험을 많이 해볼 수 있었어용 *</em>초반엔 과제가 조금씩 매일 있어서 약간 긴장감?을 갖기도 좋았습니다</p>
<h4 id="📌-협동-프로젝트">📌 협동 프로젝트</h4>
<p>마지막에 2번의 <strong>협업 프로젝트를 통해 백엔드, 프론트엔드, 기획자 분들 등이 어떻게 협업하고 소통이 전달되는지 이해</strong>하고, 같이 회의를 하며 기획자분들의 의도에 맞게 개발을 진행해보며 현업을 맛보기로 체험해볼 수 있어서 좋았습니다 !!
내가 만든 코드가 웹사이트에서 어떻게 돌아가는지 볼 수 있게 되니까 더 명확히 알게 되었던 것 같아요 </p>
<p><strong>첫번째 프로젝트</strong>는 책에 대한 내용을 알려주고 챌린지처럼 참여 하며 댓글을 다는 책관련 웹사이트개발, 
<strong>두번째 프로젝트</strong>는 단어,용어,문장 암기 웹사이트 개발을 진행하였고 프로젝트를 통해 실력이 많이 올라갔던 것 같네용 ㅎㅎ</p>
<p>밑의 사진은 두번째 프로젝트 때 개발했던 웹사이트 사진입니다 :)</p>
<p><img src="https://velog.velcdn.com/images/bread_code/post/69476dda-60bf-4d18-8340-f6bc6f811718/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/bread_code/post/4479111b-269d-4ea4-9c4d-a42fb4cf028f/image.png" alt=""></p>
<h3 id="부트캠프를-마치며">부트캠프를 마치며..</h3>
<p>파이썬, 장고 등 모르는 것들 투성이라 도망치고 싶던 때가 한두번이 아니였지만 끝까지 올 수 있게 동기부여 해주시고 차근차근 공부할 수 있게 도와주신 
오즈 초격자 캠프 운영진분들 덕분에..
2024년 12월 후반부터 새롭게 시작했던 코딩교육 ! 백엔드 코스 6개월과정을 마치게 되었습니다,, 중도포기 안한 나 칭찬해.. </p>
<p>코딩이 처음이시거나 궁금하신데 짧은 기간동안 A부터 Z까지(하기 나름이라 Z++까지 실력 점핑되신 동기분들도 봤어요..대단하심!! ) 배워보고 싶으신 분들이나 
6개월동안 밀착관리 받으면서 양질의 강사님들의 강의를 들으며 코딩공부에 전념해 보고 싶으신 분들께 추천드립니다 ㅎㅎ!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django로 웹사이트 구현하기]]></title>
            <link>https://velog.io/@bread_code/Django%EB%A1%9C-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@bread_code/Django%EB%A1%9C-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 14 Apr 2024 07:32:17 GMT</pubDate>
            <description><![CDATA[<h3 id="poetry-설치">Poetry 설치</h3>
<p>1) brew 설치</p>
<blockquote>
<p>/bin/bash -c &quot;$(curl -fsSL <a href="https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;">https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;</a></p>
</blockquote>
<p>2) poetry 설치</p>
<blockquote>
<p>brew install poetry
poetry --version #설치 잘 되었나 버전 확인</p>
</blockquote>
<p>3) poetry 세팅</p>
<blockquote>
<p>poetry init
 <img src="https://velog.velcdn.com/images/bread_code/post/ec5bef4d-9391-4cf9-b177-1bfe7dad9fa9/image.png" alt=""></p>
</blockquote>
<p>-&gt; pyproject.toml 파일 생김</p>
<h3 id="가상환경에서-django-설치">가상환경에서 Django 설치</h3>
<p>1) django 설치</p>
<blockquote>
<p>poetry add Django</p>
</blockquote>
<p>-&gt; 명령어 실행 시 .venv와 poetry.lock 파일 생김</p>
<p>2) Django 프로젝트 생성</p>
<blockquote>
<p>django-admin startproject myproject . 
   #현재 경로 폴더에 프로젝트 생성</p>
</blockquote>
<p>  -&gt; myproject폴더, manage.py 파일, db.sqlite3파일 생김.</p>
<p> 3) 서버 실행 확인</p>
<blockquote>
<p>python3 manage.py runserver</p>
</blockquote>
<h3 id="설문조사-웹사이트-구현">설문조사 웹사이트 구현</h3>
<ol>
<li><p>프로젝트 생성</p>
<blockquote>
<p>python3 manage.py startproject myproject .</p>
</blockquote>
</li>
<li><p>앱 생성</p>
<blockquote>
<p>python3 manage.py startapp users</p>
</blockquote>
</li>
<li><p>앱의 views.py에 구현하고 싶은 기능 class 만들기
&lt;users/views.py&gt;</p>
</li>
<li><p>앱의 urls.py에 구현한 기능 호출위한 url 만들기
&lt;users/urls.py&gt;</p>
</li>
<li><p>최상위 url에 즉, 프로젝트 url.py에 앱의 url 등록
&lt;myproject/urls.py&gt;</p>
<p>흐름: 최상위 url에 등록한 사이트로 접속 시 그 주소의 앱으로 연결시켜주고,
앱의 view내부 함수로 이동 시켜준다.</p>
</li>
</ol>
<h3 id="db관련-저장">DB관련 저장</h3>
<ol>
<li><p>models.py 작성
&lt;users/models.py&gt;</p>
</li>
<li><p>settings의 installed app 에 users앱 등록
&lt;myproject/installed app/users.apps.UsersConfig&gt;</p>
</li>
<li><p>테이블 등록</p>
<blockquote>
<p>python3 manage.py makemigrations
python3 manage.py migrate</p>
</blockquote>
</li>
</ol>
<h3 id="admin-superuser-등록">admin, superuser 등록</h3>
<ol>
<li>superuser 만들기<blockquote>
<p>python3 manage.py createsuperuser
<img src="https://velog.velcdn.com/images/bread_code/post/b975385b-8a31-4473-aa69-50f160e84fb4/image.png" alt=""></p>
</blockquote>
</li>
</ol>
<p> -&gt; /admin 으로 들어가 로그인 통해 접속가능</p>
<ol start="2">
<li><p>admin 등록하기
&lt;users/admin.py&gt;</p>
<h3 id="viewspy-함수-만들기-template와-연동하기">views.py 함수 만들기, template와 연동하기</h3>
<h3 id="배포하기">배포하기</h3>
<p>docker? AWS?</p>
</li>
</ol>
<h3 id="정리">정리</h3>
<p> 1.장고 설치
 2.장고 프로젝트 만들기
 3.설정하기(데이터베이스, S3)
 4.데이터베이스 초기화
 5.관리자 계정 만들기</p>
<p> 6.앱 만들기
 7.모델 설계(데이터 베이스)
 8.뷰 만들기(기능, 계산)
 9.템플릿 만들기(화면에서 표시될 내용, 양식)
 10.URL 만들기</p>
<p>대표적인 기능(화면):CRUD -&gt; Create, Read, Update, Delete
                        Post,  Get,  Put,  Delete</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Django] Django의 구조와 웹사이트 구현]]></title>
            <link>https://velog.io/@bread_code/Django-Django%EC%9D%98-%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@bread_code/Django-Django%EC%9D%98-%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Sun, 14 Apr 2024 02:19:37 GMT</pubDate>
            <description><![CDATA[<h3 id="1-django-설치">1) Django 설치</h3>
<pre><code>python3 -m pip install django</code></pre><h3 id="2-현재-저장소에-django-project-만들기">2) 현재 저장소에 django project 만들기</h3>
<pre><code>django-admin startproject myproject .</code></pre><h3 id="3-django-서버-실행">3) django 서버 실행</h3>
<pre><code>django3 manage.py runserver</code></pre><h2 id="django-구조">Django 구조</h2>
<p> <img src="https://velog.velcdn.com/images/bread_code/post/b61f4ae3-9cc3-4816-bf80-643b245a81e8/image.png" alt="">
 &lt;출처:생활코딩&gt;</p>
<ul>
<li><p>전체적인 맥락
project - app,app,app 
app - view(app의 구체적인 기능 구현 def 이루어짐) - model - DB에 접근</p>
<p>1) 사용자가 접속하여 지정한 urls.py로 위임됨
2) app으로 들어와 지정한 urls.py가 있는 views.py의 함수로 위임됨.
3) model을 이용해 DB에 접근하게 됨. (매우 편리)<br>4) DB에 접근된 데이터 받아서 사용자에게 보내줌.</p>
</li>
</ul>
<h3 id="django-app-코드">Django app 코드</h3>
<pre><code>django-admin startapp 앱이름</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Github] VSC파일과 깃허브 연동하기]]></title>
            <link>https://velog.io/@bread_code/Github-VSC%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EA%B9%83%ED%97%88%EB%B8%8C-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@bread_code/Github-VSC%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EA%B9%83%ED%97%88%EB%B8%8C-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 13 Apr 2024 08:55:32 GMT</pubDate>
            <description><![CDATA[<h3 id="1-github에서-저장소-만들기">1. github에서 저장소 만들기</h3>
<ul>
<li>public/private 고르기</li>
<li>Readme.md 생기는 추가사항 체크 (원하는대로)</li>
</ul>
<h3 id="2-vsc코드-파일-연동">2. vsc코드 파일 연동</h3>
<p>  1) git init 명령어로 파일올리기
  2) 해당 폴더와 git 저장소 연결</p>
<pre><code>   git remote add origin &#39;연결하고자하는 저장소 주소&#39;</code></pre><p>  3) 저장소 상태를 컴퓨터 폴더에 동기화 시키기</p>
<pre><code>   git pull origin main</code></pre><p>  4)  저장소 폴더에 내용 업데이트 하기</p>
<ul>
<li>현재 파일의 상태를 git에 업데이트<pre><code>git add .</code></pre><ul>
<li>바뀐 부분을 메세지와 함께 저장하는 명령어(메세지는 커밋 메세지라고함)<pre><code>git commit -m &quot;메세지&quot;</code></pre></li>
<li>새로운 버전의 정보를 저정소에 업데이트<pre><code>git push origin main</code></pre></li>
</ul>
</li>
</ul>
<ul>
<li>가상환경 들어가기</li>
</ul>
<pre><code>source .venv/bin/activate</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day5 파일과 디렉터리 (2)]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day5-%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC-2</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day5-%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC-2</guid>
            <pubDate>Tue, 09 Apr 2024 08:30:14 GMT</pubDate>
            <description><![CDATA[<h2 id="파일과-메모리">파일과 메모리</h2>
<p>  파일시스템이 파일들을 메모리에 할당하고 접근하는 방법</p>
<h3 id="파일-할당-방법">파일 할당 방법</h3>
<p>   파일시스템에선  메모리  공간을 블록이라는 공간으로 나누고 주고를 할당해 
   파일을 읽고 쓰는데 활용함.
   파일시스템은 파일정보를 파일테이블로 관리한다. 여기에는 파일이 시작하는 블록의 위치정보가  포    함되어 있다.</p>
<p>   하나의 파일은 여러개의 블록으로 이루어져 있음. 블록을 메모리에 할당할 때는 연속 방식 또는      불연속 방식을 사용할 수 있음. </p>
<p>   <img src="https://velog.velcdn.com/images/bread_code/post/271905d8-6953-4122-9176-8e80829fbaa3/image.png" alt=""></p>
<h3 id="연속방식">연속방식</h3>
<p>   <strong>연속할당방식</strong>은 보조기억장치내의 연속적인 블록에 파일을 할당하는 방식
   파일의 시작 블록이  어딨는지만 알면 파일 전체에 손쉽게 접근 가능, 벗 외부단편화 발생 할 수    있어 실제 사용하진 않음</p>
<h3 id="불연속-방식">불연속 방식</h3>
<p>   <strong>불연속할당방식</strong>은 메모리의 비어있는 공간에 데이터를 분산해서 저장하는 방식
   구분 방식에 따라 연결할당과 인덱스할당으로 구별할 수 있음</p>
<ul>
<li><p>연결할당
연결할당은 각 블록의 일부에 다음 블록의 주소를 저장하여 각 블록이 다음 블록을 가리키는, 참    조하는 형태로 할당하는 방식. 연결리스트를 활용하면 가능하다.</p>
</li>
<li><p>인덱스할당
인덱스 할당은 파일의 모든 블록 주소를 인덱스블록이라는 별도의 블록에 따로 모아 관리하는 방    식.</p>
</li>
</ul>
<h2 id="연결리스트">연결리스트</h2>
<h4 id="연결리스트-자료구조linked-list란">&#39;연결리스트&#39; 자료구조(linked List)란?</h4>
<p>   연결리스트(linked list)는 각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식    으로 데이터를 저장하는 자료구조이다.
   각 노드는 다음 노드를 가리키는, 참조하는 포인터를 포함한다.
   다음 노드를 가리키는 포인터는 다음 노드의 주소를 값으로 가지고 있다.
   각 노드의 포인터 변수는 다음 노드의 데이터의 주소를 값으로 가진다. 또한 각 포인터 변수의      주소도 따로 존재한다.</p>
<h4 id="c언어를-이용해-연결리스트를-구현하는-예제">C언어를 이용해 연결리스트를 구현하는 예제</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day5 파일과 디렉터리 ]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day5-%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day5-%ED%8C%8C%EC%9D%BC%EA%B3%BC-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC</guid>
            <pubDate>Tue, 09 Apr 2024 08:02:07 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-파일">📌 파일</h2>
<blockquote>
<p>  파일이란 의미있는 정보들을 한 덩어리로 모아 든 논리적 단위로써, 보조기억장치에 저장됨.
  물론 실행 될 때는 메인 메모리를 사용함.</p>
</blockquote>
<p>  파일은 정보 덩어리로, 나름의 구성요소가 존재함.</p>
<ul>
<li><p>파일이름</p>
</li>
<li><p>파일 실행에 필요한 정보</p>
</li>
<li><p><strong>메타데이터</strong>
파일의 속성을 뜻함. 파일의 크기, 생성된 날짜, 위치 등
메타데이터의 중요한 것 중 하나: <strong>파일 유형</strong>
평소 &#39;확장자&#39;라고 부르는 정보는 운영체제에 있어 상당히 중요한 정보이다.</p>
<p><img src="https://velog.velcdn.com/images/bread_code/post/d28da127-83b6-4e88-9408-26845ce52c19/image.png" alt=""></p>
<h3 id="파일-연산을-위한-시스템-호출">파일 연산을 위한 시스템 호출</h3>
<p>파일을 다루는 모든 작업은 운영체제에 의해 이루어진다. 따라서 응용 프로그램이 파일에 접근하려면 시스템 호출을 제공받아야 한다.</p>
<p>&lt;파일 관련 시스템 호출들&gt;</p>
<ul>
<li>파일생성, 파일열기, 파일읽기, 파일쓰기, 파일닫기, 파일삭제</li>
</ul>
</li>
</ul>
<h3 id="파일-다루는-예제-코드">파일 다루는 예제 코드</h3>
<p>&lt;23.py&gt;</p>
<pre><code># 기본적인 파일 입출력 예제

with open(&quot;number_one.txt&quot;, &quot;w&quot;) as f :
    f.write(&quot;one!&quot;)

with open(&quot;number_two.txt&quot;, &quot;w&quot;) as f :
    f.write(&quot;two!&quot;)

with open(&quot;number_three.txt&quot;, &quot;w&quot;) as f :
    f.write(&quot;three!&quot;)

with open(&quot;number_four.txt&quot;, &quot;w&quot;) as f :
    f.write(&quot;four!&quot;)

import glob # 여러개의 파일을 한번에 처리하고 싶을 때 사용하는 모듈
  # 파일 네임의 패턴을 이용해 한꺼번에 접근하기

for filename in glob.glob(&quot;*.txt&quot;, recursive=True) :
    print(filename)

import fileinput # 파일 내용에 접근하고 싶다.
with fileinput.input(glob.glob(&quot;*.txt&quot;)) as fi :
    for line in fi:
        print(line)

import fnmatch
import os

for filename in os.listdir(&#39;.&#39;): #현재 디렉토리에 있는 내용을 리스트업(.은 현재경로를 뜻함)
    if fnmatch.fnmatch(filename, &quot;??????_*.txt&quot;):
        print(filename)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/4da335a6-c111-4dba-8a44-21f5ca55ce90/image.png" alt=""></p>
<p>&lt;24.py&gt;</p>
<pre><code># 파일 관련 예외는 운영체제와 관련이 있다 !

try:
    f = open(&quot;none.txt&quot;, &quot;r&quot;)
    print(f.read())
    f.close()
except FileNotFoundError as e:
    print(e)
    print(issubclass(FileNotFoundError, OSError)) # FileNotFound가 os에러의 하위에러가 맞는지 Trrue, False로 확인</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/f3d4b13e-d518-4bbf-9f49-dfb6b36ba5df/image.png" alt=""></p>
<p>&lt;25.js&gt;</p>
<pre><code>// require: 시스템모듈 임포트해서 사용가능 함수
// fs: 파일을 다루고 싶을 때

const fs = require(&quot;fs&quot;)

fs.readFile(&quot;number_one.txt&quot;, &quot;utf8&quot;, (err, data) =&gt; {

    if(err){
        console.log(&quot;파일을 읽는 도중 오류가 발생했습니다.&quot;,err)
        return;
    }

    console.log(&quot;파일 내용 :&quot;, data)
})

// 덮어쓰기
let content = &quot;Sa Sa Sa&quot;
fs.writeFile(&quot;number_four.txt&quot;, content, (err)=&gt; {
    if(err){
        console.log(&quot;파일을 쓰는 도중 오류가 발생했습니다.&quot;, err)
        return;
    }
    console.log(&quot;파일 쓰기가 완료되었습니다.&quot;)
})

content = &quot;It is fun, right?&quot;
fs.appendFile(&quot;newfile.txt&quot;, content, (err)=&gt; {
    if(err){
        console.log(&quot;파일을 쓰는 도중 오류가 발생했습니다.&quot;, err)
        return;
    }
    console.log(&quot;파일 생성 및 쓰기가 완료되었습니다.&quot;)
})

content = &quot;It will get better&quot;
fs.appendFile(&quot;newfile.txt&quot;, content, (err)=&gt; {
    if(err){
        console.log(&quot;파일을 쓰는 도중 오류가 발생했습니다.&quot;, err)
        return;
    }
    console.log(&quot;파일 생성 및 쓰기가 완료되었습니다.&quot;)
})</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/3b20e8b5-8d52-4305-ad8c-60ca5875f096/image.png" alt=""></p>
<p>&lt;newfile.txt&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/83ce95d1-d6eb-4c2c-aea8-6b45ceed9a4d/image.png" alt=""></p>
<h2 id="📌-디렉터리">📌 디렉터리</h2>
<blockquote>
<p>  운영체제는 파일을 정돈할 수 있도록 디렉터리를 지원한다. 디렉터리는 한 개 이상의 파일을 가질   수 있고, 한개 이상의 디렉터리도 가질 수 있다. 
  디렉터리와 디렉터리는 부모와 자식 관계를 형성 할 수 있다.
  가장 위에있는 최상위 디렉터리를 가리켜 &#39;루트디렉터리&#39; 라고 한다.</p>
</blockquote>
<p>  모든 파일은 루트디렉터리에서 부터 자기자긴에 이르기까지 고유한 경로를 가짐</p>
<ul>
<li><p>윈도우 운영체제에서의 경로 예</p>
<blockquote>
<p>C:\Users\username</p>
</blockquote>
</li>
<li><p>유닉스 기반 운영체제에서의 경로 예</p>
<blockquote>
<p>/Users/username/Documents</p>
</blockquote>
<p>=&gt; 이 경로들은 모두 절대 경로!</p>
<p>&lt;상대경로&gt;
현재 내가 위치해 있는 디렉토리에서 특정 파일까지의 경로</p>
<ul>
<li><p>윈도우 운영체제에서의 상대경로 예</p>
<blockquote>
<p> ..\folder\document.txt</p>
</blockquote>
</li>
<li><p>유닉스 기반 운영체제에서의 상대경로 예</p>
<blockquote>
<p> ../directory/document.txt</p>
</blockquote>
</li>
</ul>
<h4 id="디렉토리와-파일을-구별해서-생각하기-쉽지만-사실은-디렉터리도-파일의-일종이다-">디렉토리와 파일을 구별해서 생각하기 쉽지만, 사실은 디렉터리도 파일의 일종이다 !</h4>
<p>일반 파일에는 데이터가 저장되어 있지만, 디렉터리에는 파일 정보가 저장되어 있다.</p>
<p>디렉터리에 저장된 파일 정보는 테이블 형태로 관리된다.
테이블 행 하나하나를 가리켜 디렉터리 엔트리라고 부른다.</p>
<h3 id="실습-예제-코드">실습 예제 코드</h3>
<p>&lt;26.py&gt;</p>
<pre><code>   # os 파일 시스템 관련 함수
 import os

 pwd = &quot;/Users/hu_un00/Desktop/os-exam&quot;

 # 디렉터리 내부 리스트 업
 filenames = os.listdir(pwd)
 # print(filenames) # pwd속 파일 이름들 주르륵 나옴.

 # 디렉터리인지 아닌지  여부
 print(os.path.isdir(filenames[0])) #filenames의 첫번째인 one_txt는 파일이     라서 디렉터리아니라고 나옴
 print(os.path.isdir(pwd + &quot;/anyone&quot;)) # 폴더이므로 디렉터리라고 나옴

 # 파일인지 아닌지 여부
 print(os.path.isfile(filenames[0])) # 위와 반대
 print(os.path.isfile(pwd + &quot;/anyone&quot;)) 

 # 파일이름과 확장자 분리
 filepath = pwd + &quot;/&quot; + filenames[0]
 print(filepath)
 name, ext = os.path.splitext(filepath)
 print(name)
 print(ext)</code></pre><p>&lt;결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/f642134d-f0e1-45a2-94c3-f59e27e74ed1/image.png" alt=""></p>
<p>&lt;27.py&gt;</p>
<pre><code>   # 경로와 확장자 이용해 파일 찾고, 내용 읽기

 import os

 def searchFile(dirname, extension) :
     filenames = os.listdir(dirname)
     for filename in filenames :
         filepath = os.path.join(dirname, filename)
         if os.path.isdir(filepath) :
             searchFile(filepath, extension)
         elif os.path.isfile(filepath):
             name, ext = os.path.splitext(filepath)
             if ext == extension:
                 with open(filepath, &quot;r&quot;, encoding=&quot;utf-8&quot;) as f :
                     print(f.read())

 searchFile(&quot;/Users/hu_un00/Desktop/os-exam&quot;, &quot;.txt&quot;)</code></pre><p>&lt;진행결과&gt;
=&gt; txt파일 내용을 읽음</p>
<p>&lt;28.py&gt;</p>
<pre><code>  # 파일의 복사 또는 이동
 import os
 import shutil

 pwd = &quot;/Users/hu_un00/Desktop/os-exam&quot;
 filenames = os.listdir(pwd)

 for filename in filenames:
     if &quot;tokyo&quot; in filename:
         origin = os.path.join(pwd, filename)
         print(origin)
         # shutil.copy(origin, os.path.join(pwd,&quot;copy.txt&quot;))
         shutil.move(origin, os.path.join(pwd, &quot;anyone&quot;)) </code></pre><p>&lt;실행결과&gt;
1) copy.txt에 복사됨.
2)tokyo.txt 가 anyone폴더로 이동</p>
<p>&lt;29.py&gt;</p>
<pre><code>  # 파일 경로를 문자열이 아닌 객체로 다루기
 import os
 import pathlib

 for p in pathlib.Path.cwd().glob(&quot;*.txt&quot;): #현재 워팅디렉토리 반환해주는 함수
     new_p = os.path.join(p.parent, p.name)
     print(new_p)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/024ab6de-991a-415e-8969-8277f3093059/image.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 페이지 교체]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B4</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B4</guid>
            <pubDate>Mon, 08 Apr 2024 07:38:27 GMT</pubDate>
            <description><![CDATA[<h2 id="스레싱thrashing">스레싱(thrashing)</h2>
<p>  <img src="https://velog.velcdn.com/images/bread_code/post/d99c019f-c9bf-4fc2-a841-9064a79df515/image.png" alt=""></p>
<blockquote>
<p>   프레임이 부족하면 페이지 폴트가 발생하게 되고 빈번한  페이지 폴트는 CPU사용률을 현저히 떨어뜨린다. CPU사용률이 떨어지면 운영체제는 더 많은 프로세스를 올리려고 하고 이로인해 더 잦은 페이지폴트로 이어져 악순환에 빠지게 된다. 이러한 문제를 &#39;스레싱(thrashing)&#39;이라고 한다.</p>
</blockquote>
<p>   이러한 문제 스레싱을 해결하기 위한 소프트웨어적 해결책으로 Working Set이 있다.</p>
<h2 id="워킹셋-working-set-이란">워킹셋 working set 이란</h2>
<p>   &quot;working set&quot;이란 프로세스가 일정 기간동안 자주 사용하는 페이지들의 집합, 
   프로그램의 <em>locality특성</em> 을 이용하여 자주 참조되는 워킹셋을 <strong>주기억장치</strong>에 상주시킴으    로서  페이지 부재와 페이지 교체 빈도를 줄인다. 
   시간이 지남에 따라서 자주 사용하는 페이지는 바뀌게 되므로 <strong>워킹셋은 가변적</strong>이다.</p>
<ul>
<li>여기서 페이지의 부재란 프로세스 실행 시 참조할 페이지가 주기억장치에 없는 현상을 말함.
페이지 부재율에 따라 주기억장치에 있는 페이지프레임의 수를 늘리거나 줄여 페이지 부재율을      적정 수준으로 유지하는 방식</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day4 메모리와  페이지 교체(3)]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day4-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%99%80-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B43</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day4-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%99%80-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B43</guid>
            <pubDate>Mon, 08 Apr 2024 06:39:07 GMT</pubDate>
            <description><![CDATA[<h2 id="페이지-교체">페이지 교체</h2>
<p>CPU가 특정 페이지에 접근하는 명령어를 실행 했을 때, 해당 페이지가 스왑영역(유효비트가 0)에 있어서 당장 실행시킬 수 없는 상태일 경우에는 &#39;페이지 폴트&#39;예외가  발생.</p>
<p>페이지 폴트 예외  발생시 스왑인 작업으로 유효비트를 0에서 1로 스와핑 잡업이 먼저 진행된 후 프로세스를 실행할 수 있는 상태를 만들어 준후 프로세스가 실행된다.</p>
<p>실행할 모든 프로세스를 메모리에 올려두는 것은 시스템에 부담이 될 수 있는 만큼 당장 필요한 페이지만을 메모리에 우선 적재하는 방법을 가리켜 &#39;요구 페이징&#39;이라 한다.</p>
<h2 id="페이지-교체-정책">페이지 교체 정책</h2>
<p> 위와 같이 스왑인을 실행하기 위해 메인메모리에 빈공간을 만들어 주기 위해 메인메모리에 들어찬 페이지 중 어떤 페이지를 스왑 영역으로 보낼 것인지 결정하고 그것을 처리하는 것을 페이지 교체라고 한다. 페이지 교체 정책에는 세가지 대표적인 방식이 있다.</p>
<h3 id="--선입선출">- 선입선출</h3>
<p><img src="https://velog.velcdn.com/images/bread_code/post/69231e33-efff-43fa-9a78-ae3e12295196/image.png" alt="">
&lt;출처: 유노코딩&gt;
   페이지 폴트 발생 시 가장 먼저 들어간 페이지1이 빠지고 그 자리에  페이지4가 들어가게 된다.
   그리고 페이지1이 다시 들어가고 싶다면 그다음 들어간 페이지3이 빠지고 그 자리에 페이지1이      들어간다.</p>
<h3 id="--최적-페이지-교체">- 최적 페이지 교체</h3>
<p>  CPU에 의해 참조되는 횟수를 고려해서 자주 사용될 예정인 페이지를 내버려 두고, 
  사용이 거의 되지 않을 예정인 페이지를 교체하는 방식이다.
  어떤 프로세스가 얼마나 빈번히 사용될지 알 수 없어 이론적으로만 존재하는 방식이다.</p>
<h3 id="--lruleast-recently-used">- LRU(Least Recently Used)</h3>
<p><img src="https://velog.velcdn.com/images/bread_code/post/63d99462-a739-4f24-9280-2cf7e542af89/image.png" alt=""></p>
<p> 최근 사용 빈도가 가장 적은 페이지를 선택하는 방법임. 최근에 오랫동안 사용되지 않은 페이지가 사용되지 않을 확률이 높다 생각해 스왑 영역으로 보내는 방법.</p>
<h3 id="스래싱thrashing">스래싱(thrashing)</h3>
<blockquote>
<p>  이 모든 것의 근본적인 이유는 메모리 공간의 부족, 즉 프레임 부족이다.
  프레임이 부족하면 페이지 폴트가 자주 발생한다. 페이지 폴트가 발생하면 잦은 스와핑  작업으로 인해 CPU사용률이 떨어지게 된다.</p>
</blockquote>
<blockquote>
<p>  CPU사용률이 떨어지면 운영체제는 더 많은 프로세스를 메모리에 올리려 하고, 이는 더 잦은 페이지 폴트로 이어져 악순환에 빠지게 되는데 이러한 문제를 &#39;스레싱&#39;이라고 한다.</p>
</blockquote>
<p>  이를 해결하는 가장 쉬운 방법은 메인메모리를 크게 해주면 되는데 쉬운 방법이 아니다.</p>
<h3 id="실습코드">실습코드</h3>
<p> &lt;선입선출 예제&gt;</p>
<pre><code> # 선입선출 모델 구현

    class PageReplacementFIFO :
        def __init__(self, capacity):
            self.capacity = capacity
            self.pages = []

        def access_page(self, page) :
            if page not in self.pages :
                if len(self.pages) &gt;= self.capacity :
                    self.pages.pop(0) # 제일 앞에 있는 친구를 뺸다.
                self.pages.append(page)

        def status(self):
            print(&quot;현재 페이지 상태:&quot;, self.pages)

    page_replacement = PageReplacementFIFO(capacity=3)

    page_replacement.status()

    page_replacement.access_page(3)
    page_replacement.status()
    page_replacement.access_page(2)
    page_replacement.status()
    page_replacement.access_page(1)
    page_replacement.status()

    page_replacement.access_page(4)
    page_replacement.status()</code></pre><p> &lt;실행결과&gt;
 <img src="https://velog.velcdn.com/images/bread_code/post/78565016-4af8-440e-b829-e6c2b4b8a42b/image.png" alt=""></p>
<p>가장 먼저 들어간 3이 빠지고 4가 들어가는 것을 볼 수 있음.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day4 메모리와  페이지 교체(2)]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day4-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%99%80-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B42</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day4-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%99%80-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B42</guid>
            <pubDate>Mon, 08 Apr 2024 05:57:09 GMT</pubDate>
            <description><![CDATA[<h2 id="가상-메모리-관리">가상 메모리 관리</h2>
<h3 id="고정-분할-방식페이징">고정 분할 방식(페이징)</h3>
<p>  페이징기법은 메모리 공간을 일정한 크기의 페이지로 나누어 다룬다. =&gt; 불연속적 할당</p>
<p>  <img src="https://velog.velcdn.com/images/bread_code/post/8dcce372-4746-4db6-9d42-46df6eb2b305/image.png" alt=""></p>
<ul>
<li><p><strong>논리주소 공간</strong>
사용지와 프로세스가 참조하는 공간으로 실제 메모리보다 더 큰 공간
보조기억장치의 크기를 지원받아 크기를 키운 것임.
논리주소공간의 조각은 페이지라고 부름</p>
</li>
<li><p><strong>물리주소 공간</strong>
실제 메모리의 공간을 뜻함. 물리주소공간의 조각은 프레임이라고 부름.</p>
</li>
</ul>
<blockquote>
<p>   페이징은 CPU가 논리주소를 통해 메모리에 접근하고 운영체제가 이를 물리주소로 변환하여 실제      메모리에 올리는 방식임. 논리주소공간이 물리주소공간보다 크기때문에 부족한 공간은 스와핑 방법    으로 이뤄지는데, 페이징에서는 이 용어를 &#39;페이지 인&#39; 과 &#39;페이지 아웃&#39;으로 바꾸어 부름.</p>
</blockquote>
<ul>
<li><p><strong>특징</strong>
페이징 기법은 프로세스에게 불연속적으로 주소를 할당함. 연속적으로 주소를 할당시 외부 단편화가 발생할 수 있지만 불연속적인 방법은 내부 단편화가 발생 할 수도 있음.</p>
</li>
<li><p><em>페이지 테이블은 페이지 번호와 프레임 번호를 짝지어 주는것이고  프로세스마다 각자의 페이지 테    이블을 가지고 있어 각 프로세스의 테이블은 메모리에 적제되어 있다. *</em>   </p>
</li>
<li><p><em>따라서 물리공간에 불연속적으로 할당되어 있다고 해도 다음에 실행해야할 프로세스를 적절하게 찾    아갈 수 있다.*</em></p>
</li>
</ul>
<h3 id="페이지-테이블--엔트리">페이지 테이블  엔트리</h3>
<ul>
<li><p>접근비트: 페이지가 메모리로 올라온 후 데이터에 접근성이 있었는지 알려주는 비트</p>
<pre><code>    메모리에 읽기나 실행작업을 했다면 1로 바뀌게 됨.</code></pre></li>
<li><p>변경비트: 페이지에 메모리가 올라온 후 데이터의 변경이 있었는지 알려주는 비트</p>
<pre><code>    메모리에 쓰기작업이 있었다면 1로 바뀌게 됨.</code></pre></li>
<li><p>유효비트: 페이지가 어디에 있는지 알려주는 비트. 0이라면 페이가 스왑영역, 1이라면 물리메모             리에 있다는 뜻. CPU가 유효비트가 0인 스왑영역에 접근하려 하면 페이지폴트라는 </p>
<pre><code>    예외가 발생. 이가 발생하면 프로세스를 바로  실행할 수 없다는 의미.</code></pre></li>
<li><p>보호비트: 페이지에 대한 읽기, 쓰기, 실행권한이 어떻게 되는지 나타내는 비트</p>
<pre><code>    100 은 읽기 권한만 있고, 111은  모든 권한이 다 있다는 뜻.</code></pre><h3 id="페이지드-세그멘테이션">페이지드 세그멘테이션</h3>
<blockquote>
<p>   세그멘테이션과 페이징을 혼합한 방식
세그멘테이션은 가변분할방식이여서 데이터,스텍,코드 영역등 논리적으로 나눠져 있는 영역을 나눠    서 관리 가능, 벗 외부단편화 문제 발생가능
페이징은 논리적인 영역들을 나눠서 관리는 못함. 벗 메모리 효율이 좋음</p>
</blockquote>
<p>페이지드 세그멘테이션에서는 세그멘테이션 테이블이라는 것을 관리.
세그먼트 번호, 권한비트, 페이지번호, 크기 등으로 구성되어 있음. 권한비트로 코드영역,스택영역등에 대한 권한에 차이를 부여할 수 있음. </p>
<h3 id="실습-코드">실습 코드</h3>
<pre><code>foods = [&quot;햄버거&quot;, &quot;샐러드&quot;, &quot;비스킷&quot;]

print(id(foods))
# id: 참조자(변수)가 어떤 논리 메모리 주소(논리주소공간)를 참조하고 있는지 반환해주는 함수
print(hex(id(foods))) #16진수 값

mv = memoryview(b&quot;happy day&quot;)

print(mv)

print(mv[0]) #h에 관한 주소
print(mv[1]) # a
print(mv[2]) # p
print(mv[3]) # p</code></pre><pre><code>   import psutil
import os

print(&quot;메모리 사용량 조회하기&quot;)

memory_dict = dict(psutil.virtual_memory()._asdict()) #시스템메모리 사용량에 대한 통계를 튜플형태로 반환해줌/그것을 딕셔너리로 바꿈
print(memory_dict)

total = memory_dict[&#39;total&#39;] #총량
available = memory_dict[&#39;available&#39;] # 즉시사용가능한양
percent = memory_dict[&#39;percent&#39;] # available제외한 비율(사용중인 비율)

print(f&quot;메모리  총량 : {total}&quot;)
print(f&quot;메모리  즉시 제공 가능량 : {available}&quot;)
print(f&quot;메모리  사용량 : {percent}&quot;)

pid = os.getpid()
current_process = psutil.Process(pid)

kb = current_process.memory_info()[0] / 2 ** 20 # 현재 나의  프로세스가  몇키로바이트  쓰는지 알수 잇음.
print(f&quot;메모리 사용량 : {kb:.2f} KB&quot;)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/d951aed1-fa72-4e26-9dd6-dacc5f7199a9/image.png" alt=""></p>
</li>
</ul>
<pre><code>import tracemalloc # 메모리 추적 파이썬 3.4부터 지원됨

tracemalloc.start()

# 메모리 할당이 진행되는 작업 아무거나 해본 것임!
data = [b&#39;%d&#39; % num for num in range(1,10001)]
joined_data = b&#39; &#39;.join(data)

current, peak = tracemalloc.get_traced_memory()
# 현재사용량, 최대사용량
print(f&#39;현재 메모리 사용량: {current / 10 ** 6}MB&#39;)
print(f&#39;최대 메모리 사용량: {peak / 10 ** 6}MB&#39;)

tracemalloc.stop()

traced = tracemalloc.get_tracemalloc_memory() #프로세스를 추적(트레이스말록)하느라 쓴 메모리
print(traced / 10 ** 6)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/85caae25-cb03-4921-9b33-49d115de19d9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day4 메모리와  페이지 교체]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day4-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%99%80-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B4</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day4-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%99%80-%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%90%EC%B2%B4</guid>
            <pubDate>Mon, 08 Apr 2024 04:49:22 GMT</pubDate>
            <description><![CDATA[<h2 id="메모리의-이해">메모리의 이해</h2>
<p> 컴퓨터엔 다양한 메모리들 존재
 <img src="https://velog.velcdn.com/images/bread_code/post/3782fd6c-56fc-4793-be3c-782f076ed65d/image.png" alt=""></p>
<p> CPU엔 레지스터라는 메모리 있었고, 캐시메모리, RAM, 하드디스크 등 메모리도 있음.
 얘네들은 계층구조를 형성.</p>
<h4 id="--레지스터">- 레지스터</h4>
<blockquote>
<p> 레지스터는 CPU안에서 연산을 위한 저장소를 제공, 속도가빠르지만 용량은 크지 않음.</p>
</blockquote>
<h4 id="--캐시-메모리">- 캐시 메모리</h4>
<blockquote>
<p>  CPU와 RAM사이에 중간 저장소 역할을 하는 메모리, 레지스터와 RAM사이에 데이터 이동이 있을     때 그 속도를 보완하는 역할을 하는 메모리. 캐시는 이미 사용된 데이터를 임시로 저장해서 메인메   모리인 RAM으로부터 데이터를 가져오는 시간보다 더 빠르게 데이터를 가져올 수 있게 해줌.
  CPU입장에서는 바로 꺼내 쓸 수 있는 주머니인셈.
  캐시메모리는 용도에 따라 L1과 L2캐시로 나누어짐.</p>
</blockquote>
<h4 id="--메인-메모리-ram">- 메인 메모리 (RAM)</h4>
<blockquote>
<p>  RAM은 컴퓨터의 메인메모리로 불림. 메인메모리는 프로세스와 운영체제들이 올라가는 공간이다.
  HDD나 SSD같은 보조기억장치보다 비싸서 데이터를 저장하기 보다는 실행 중인 파일을 올리기 위해  사용함</p>
</blockquote>
<h4 id="--보조기억장치hddssd">- 보조기억장치(HDD/SSD)</h4>
<blockquote>
<p>  크고 작은 파일들을 저장하기 위한 용도로 주로 사용됨. 계층구조에서 제일 끝단에 있는 만큼 속도가 느리지만 그만큼 용량은 크다. 일반적으로 가장 저렴하고 보조기억장치의 용량이 가장 크다. </p>
</blockquote>
<h4 id="--휘발성비휘발성">- 휘발성/비휘발성</h4>
<p>  컴퓨터 전원이 꺼졌을 때 데이터가 사라지는 것을 휘발성이라고 하는데
  레지스터, 캐시, 메인메모리는 휘발성 메모리, 보조기억장치는 비휘발성 메모리이고 컴퓨터가 꺼져   도 데이터를 저장한다.</p>
<h3 id="메모리-할당-방식">메모리 할당 방식</h3>
<p>멀티프로세스 운영체제에서 메모리를 관리하는 방법</p>
<p>여러개의 프로세스를 메모리에 올려야 한다면, 선택할 수 있는 방식은 두가지이다. 가변 분할 방식과 고정 분할 방식이 있다.</p>
<ul>
<li><p>가변분할방식
프로세스의 크기에 따라 가변적으로 나누는 방식. 프로세스 크기가 크면 큰대로, 작으면 작은데로 할당해줌. 연속 메모리 할당 또는 세브먼테이션 이라고 불리기도 함.</p>
</li>
<li><p>고정분할방식
메모리를 고정으로 미리 나누어 놓은 후 나누어진 메모리를 프로세스 크기만큼 할당해주는 것.
비연속 메모리 할당 또는 페이징으로 불리기도 함.</p>
<h3 id="가변-분할-방식">가변 분할 방식</h3>
<p> 연속 메모리 할당</p>
<p> 실행상태의 프로세스는 메인 메모리에 올리고, 실행상태가 아닌 프로세스들은 보조장치에 따로 마련된 <em>스왑 영역</em> 에 올린 다음 프로세스의 상태변화에 따라 두 공간 사이에서 프로세스가 이동하는(교환되는)것을 &#39;스와핑&#39;이라함.
실행상태가 아닌 프로세스들을 이 영역으로 부터 가져다가 메인 메모리에 올려 실행하는 &#39;스왑 인&#39;
실행중인 것을 스왑 영역으로 보내는 것을 &#39;스왑아웃&#39;, 두가지를 처리하는 것을 통틀어  스와핑이라고 부름.</p>
<p><img src="https://velog.velcdn.com/images/bread_code/post/8d8fe2cf-41a9-46d7-a9c7-9839344d10c3/image.png" alt="">
&lt;출처:유노코딩&gt;</p>
<ul>
<li>스와핑을 통한 프로세스관리의 예
주황색이 실행중인 프로세스임
돌려야하는 총량이 메인메모리의 용량을 초과할 경우 스왑영역이 있어 실행 시킬 수 있다.</li>
</ul>
<h3 id="외부-단편화">외부 단편화</h3>
<p>프로세스를 메모리에 연속 배치하는 작업을 하다보면 메모리가 낭비되는 &#39;외부 단편화&#39;상황이 발생   하기도 함.
<img src="https://velog.velcdn.com/images/bread_code/post/c7758d3a-b46f-4a98-aa20-af440a23cd3f/image.png" alt="">
조각모음이라는 방법을 통해 공간을 올려주어 들어갈 수 있게 만들 수 있지만
이는 시스템에 무리를 주는 방법이라 빈번하게 쓰면 안된다.</p>
<h3 id="실습코드">실습코드</h3>
<p>&lt;실습.py&gt;</p>
<pre><code>  # 메모리를 아끼기 위해 존재하는 레퍼런스 카운트와 가비지  컬렉션에 대한 에제

# 문자열 객체를 변수 my_name이 참조했다
# 레퍼런스 카운트가 1인 상태
my_name = &quot;goguma&quot; # 고구마

# 레퍼런스 카운트가 2인 상태
your_name = my_name

my_name = 1
your_name = 2

# 레퍼런스 카운트가 0이 되었다. 0이되면 제거 대상이고 이를 가비지컬렉션(쓰레기 모음)이라고 한다.
# 소멸 대상</code></pre><p>&lt;실습.js&gt;</p>
<pre><code> // 객체가 두개, 그에 대한 참조가 2개가 됬다.
let players = {
    boys: {
        Bergkamp : &quot;Striker&quot;
    }
}

let persons = players
// 레퍼런스  카운트는 올라가고 가비지 컬렉션은 참조힐게 없는 상태임.

players = [&quot;Son&quot;, &quot;Park&quot;]
// 이제 players는 레퍼런스카운트에서 빠짐. 손과 박을 가르키는 변수가 됨.
// persons가 유일한 boys참조하는 애됨.

let human = persons.boys 

persons = &quot;persons&quot;
// 이제 boys가르키는 애 human 뿐임

human = null
// 이제 boys 참조하는애 없음 레퍼런스 0됨.
// 제거대상</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day3 프로세스 통신과 동기화(3)]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day3-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%ED%86%B5%EC%8B%A0%EA%B3%BC-%EB%8F%99%EA%B8%B0%ED%99%943</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day3-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%ED%86%B5%EC%8B%A0%EA%B3%BC-%EB%8F%99%EA%B8%B0%ED%99%943</guid>
            <pubDate>Fri, 05 Apr 2024 09:57:31 GMT</pubDate>
            <description><![CDATA[<h2 id="데드락deadlock">데드락(Deadlock)</h2>
<p>프로세스 실행과정에 발생할 수 있는 정체상황</p>
<p>프로세스들은 순서를 기다리다 기다리는 대상이 꼬꼬물(꼬리에꼬리물기)해서 아무도 작업을 진행하지 못하는 상태가 종종 발생하는데 이것을 데드락이라고 함.
데드락이 발생하는 이유는 공유자원 때문 !</p>
<p><strong>&lt;데드락의 네 가지 조건&gt;</strong>
데드락은 다음 네 가지 조건이 모두 만족되는 경우에만 발생할 수 있음. 
but 모두 만족한다고 무조건 발생하는 것이 아니라 발생할 수도 있다 라는 것임.</p>
<ul>
<li><p><strong>상호배제(Mutual exclusion)</strong>
어떤 프로세스가 공유자원을 사용중이라면 해당 공유자원은 다른 프로세스가 접근 할 수 없어야 함</p>
</li>
<li><p><strong>비선점(No preemption)</strong>
어떤 프로세스가 공유자원을 가지고 있을 때 다른 프로세스가 그 공유자원을 빼앗을 수 없어야 함(선점 X)</p>
</li>
<li><p><strong>점유 및 대기(Hold and wait)</strong>
어떤 프로세스가 공유자원을 가지고 있는 상태일 때 다른 프로세스가 그 공유자원을 사용하기 위해 기다리고 있는 상태에 있어야함</p>
</li>
<li><p><strong>원형 대기(Circular waite)</strong>
점유 및 대기를 하는 프로세스들의 관계가 꼬꼬물해서 둥글게 형성되어있는 상황이어야 발생 할 수 있음</p>
<h3 id="일일과제">일일과제</h3>
<p>데드락, 즉 교착상태에 대해서 비유적으로 설명할 때 주로 사용되는 예시로 
&#39;식사하는 철학자 문제&#39;라는 것이 있다.
이에 대해 조사하고 정리하는 글을 써보자.</p>
<h2 id="식사하는-철학자-문제">식사하는 철학자 문제</h2>
<p><img src="https://velog.velcdn.com/images/bread_code/post/9359e85d-023b-4cfd-b1b3-5320bbac8830/image.png" alt=""></p>
</li>
</ul>
<p>5명의 철학자가 원탁에 앉아서 식사를 한다. 철학자들 사이에는 젓가락이 하나씩 놓여 있고, 철학자들은 다음의 과정을 통해 식사를 한다.</p>
<blockquote>
<ol>
<li>일정 시간 생각을 한다.</li>
<li>왼쪽 전가락이 사용 가능해질 때까지 대기한다. 만약 사용 가능하다면 집어든다.</li>
<li>오른쪽 젓가락이 사용 가능해질 때까지 대기한다. 만약 사용 가능하다면 집어든다.</li>
<li>젓가락 한 쌍을 얻었다면 일정 시간만큼 식사를 한다.</li>
<li>오른쪽 젓가락을 내려놓는다.</li>
<li>왼쪽 젓가락을 내려놓는다.</li>
<li>다시 1번으로 돌아간다.</li>
</ol>
</blockquote>
<p>간단하게 생각해, 만약 모든 철학자들이 동시에 자신의 왼쪽 젓가락을 잡는다면, 모든 철학자들이 자기 오른쪽의 젓가락이 사용 가능해질 때까지 기다려야 한다. 그런데 모든 철학자들이 그러고 있다. 이 상태에서는 모든 철학자가 영원히 3번 상태에 머물러있어 아무것도 진행할 수가 없게 되는데, 이것이 교착(Deadlock)상태이다.</p>
<ul>
<li>교착상태(Deadlock) - 모두 식사를 하지 못하기 때문에 젓가락을 내려놓을 일이 없고, 3번 과정으로 넘어가지 못하기 때문이다.</li>
<li>기아현상(starvation) - 이러한 상황이 지속된다면 철학자들 모두 굶어죽고 말 것이다.</li>
</ul>
<p>해당 문제는 OS의 Deadlock, Starvation을 설명하기 위한 상황으로 비유한 대상은 아래와 같다.</p>
<ul>
<li>젓가락 -&gt; 자원(Resource)</li>
<li>철학자 -&gt; Process(or Thread)</li>
<li>젓가락 한 쌍(2개) -&gt; Process가 필요한 자원의 수</li>
</ul>
<h4 id="데드락-발생-규칙-4가지">*[데드락 발생 규칙 4가지]</h4>
<ul>
<li>Mutual exclusion : 다른 철학자가 사용 중인 젓가락을 서로 공유하며 사용할 수 없습니다.</li>
<li>Hold and wait : 철학자가 젓가락(자원) 1개를 가지고 있는 상태에서, 다른 철학자가 사용 중인 젓가락을 요청합니다.</li>
<li>No preemtion : 규칙상 다른 철학자가 가지고 있는 젓가락을 함부로 빼앗거나 선점할 수 없습니다.</li>
<li>Circular wait : 철학자들이 서로 꼬리에 꼬리를 무는 형태로 젓가락을 기다리고 있습니다.</li>
</ul>
<p>=&gt; 따라서, 철학자들은 현재 Deadlock에 걸린 상황이며 더 이상 식사를 진행하지 못하고 있고
뿐만 아니라, 젓가락(자원)을 요청하고 있으나, 계속해서 할당받지 못하는 상황인 Starvation까지 발생한 상황이다.</p>
<h3 id="문제-해결-방법">문제 해결 방법</h3>
<h4 id="방법1-젓가락-개수-늘리기">방법1. 젓가락 개수 늘리기</h4>
<p> 젓가락 개수를 5개에서 6개로 늘려 최악의 경우 5명이 젓가락을 하나씩 집어도 1명은 2개의 젓가락으로 식사를 마치고 이 과정을 반복한다.</p>
<h4 id="방법2-철학자-위치-구분홀짝">방법2. 철학자 위치 구분(홀짝)</h4>
<ol>
<li>홀수 번 철학자, 짝수 번 철학자를 구분한다.</li>
<li>홀수 번 철학자 인 경우는 젓가락을 왼쪽, 오른쪽 순으로 집어서 밥을 먹고 젓가락을 왼쪽, 오른쪽 순으로 놓는다.</li>
<li>짝수 번 철학자인 경우는 젓가락을 오른쪽, 왼쪽 순으로 집어서 밥을 먹고 젓가락을 오른쪽, 왼쪽 순으로 놓는다.</li>
</ol>
<ul>
<li>교착상태의 4가지 필요조건 중 &#39;원형대기&#39;를 해결하여 이 문제를 해결한다.</li>
</ul>
<h4 id="방법3-철학자-5명이-앉을-수-있는-테이블에-최대-4명만-앉을-수-있도록-허용한다">방법3. 철학자 5명이 앉을 수 있는 테이블에 최대 4명만 앉을 수 있도록 허용한다.</h4>
<p>  만약 5좌석에서 4명만 앉힐 수 있도록 허용한다면, 3명이 젓가락을 한 개씩 가지고 있다고 하더라도 최소한 나머지 1명은 젓가락을 2개 얻을 수 있으므로 식사가 가능하다.</p>
<p>따라서 1명이 식사를 마치면, 언젠가는 다른 철학자들도 식사를 할 수 있으므로 Deadlock 발생 상황을 배제할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day3 프로세스 통신과 동기화(2)]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day3-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%ED%86%B5%EC%8B%A0%EA%B3%BC-%EB%8F%99%EA%B8%B0%ED%99%942</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day3-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%ED%86%B5%EC%8B%A0%EA%B3%BC-%EB%8F%99%EA%B8%B0%ED%99%942</guid>
            <pubDate>Fri, 05 Apr 2024 06:56:40 GMT</pubDate>
            <description><![CDATA[<h2 id="동기화">동기화</h2>
<p>프로세스들은 서로 독립적이지만, 프로세스 간 통신을 하거나 같은 대상에 대한 작업을 함으로써 협력할 수 있다. 그런데 이때, 동시다발적으로 작업을 처리하면 문제가 발생 할 수 있다.
이를 위해 프로세스 동기화가 필요하고, 스레드간에도 이것이 적용된다.</p>
<h3 id="공유자원과-임계구역">공유자원과 임계구역</h3>
<blockquote>
<p>프로세스 간 통신에서는 공동으로 이용하는 변수가 파일, 입출력 기기 등이 존재하고
이를 가리켜 &#39;공유자원&#39;이라 한다.
공유자원은 각 프로세스의 접근 순서에 따라 결과가 달라질 수 있는데, 프로세스가 동시에 실행할 경우 문제가 발생할 수 있는 영역을 가리켜 &#39;임계구역&#39;이라고 한다.</p>
</blockquote>
<p>예를들어 프로세스A는 +1시키고, 프로세스B는 -1시킬 때 공유자원에 하나씩 접근하면 다시 0이되지만 동시에 접근하게 되면 +1만이 넣어지거나 -1만이 넣어질 수 있다.</p>
<ul>
<li><strong>상호배제</strong>
동기화기법은 임계구역에서 발생 할 수 있는 문제를 해결하기 위한 기법이고,
이 동기화기법 구현 시에는 &#39;상호배제&#39;라는 조건을 만족시켜야 함.
상호배제란, 하나의 프로세스가 임계구역에 들어갔다면 다른 프로세스는 임계구역에 들어갈 수 없다는 조건을 뜻함.</li>
</ul>
<h4 id="동기화-기법들">&lt;동기화 기법들&gt;</h4>
<h4 id="--뮤텍스-락">- 뮤텍스 락</h4>
<p><img src="https://velog.velcdn.com/images/bread_code/post/3be30485-6df9-412f-925e-fbbc3862e911/image.png" alt=""></p>
<p> 뮤텍스락은 동시에 접근되면 안되는 임계구역에 동시에 접근 할 수 없도록 만드는 도구이다.
 임계구역에 진입하는 프로세스는 뮤텍스락을 이용해 임계구역의 문을 잠글 수 있음.
 뮤텍스락은 두개의 대표적인 함수를 호출해 동작을 수행함
 : - acquire(): 프로세스가 임계구역에 진입하기 전에 호출하는 문잠그기 함수</p>
<ul>
<li>release(): 임계구역에서 볼일을 마치고 나올 때 문잠금 해제하는 함수</li>
</ul>
<h4 id="--세마포어">- 세마포어</h4>
<p><img src="https://velog.velcdn.com/images/bread_code/post/7948a90c-6233-44ee-95bb-97ac9a69e676/image.png" alt=""></p>
<p> 뮤텍스락은 공유자원이 1개있을 때라 생각하고 만든 동기화 방법이지만,
 세마포어는 공유자원이 여러개 있을 때도 사용 가능한 동기화 방법임.
 어떤 프로세스가 아무도 이용하지 않는 공유자원1에 접근하려 할 때 운영체제는 세마포어라는 열쇠를  그 프로세스에게 건네주어 공유자원1에 접근가능하게 함.
 새로운 프로세스가 와서 공유자원1에 접근하려 할 때 이미 열쇠(세마포어)이용중이니 기다리라고 함
 세마포어도 두개의 대표적인 함수를 호출해 동작을 수행함
 : - wait(): 프로세스가 임계구역에 들어갈 수 있는지 기다려야하는지 알려주는 함수</p>
<ul>
<li>signal(): 기다리고있는 프로세스에게 이제 들어가도 된다고 신호전달해주는 함수</li>
</ul>
<h4 id="실습코드">실습코드</h4>
<p>&lt;뮤텍스락 걸어주지 않아 생기는 문제 확인&gt;</p>
<pre><code>  from multiprocessing import Process, Value
  # Value: 프로세스간의 값을 공유하게 만들고 싶을 때 사용하는 파이썬의 생성자함수

  def counter1(snum, cnt): # snum:공유하는숫자, cnt:몇번연산을 수행할지
      for i in range(cnt):
          snum.value += 1

  def counter2(snum, cnt): # snum:공유하는숫자, cnt:몇번연산을 수행할지
      for i in range(cnt):
          snum.value -= 1

  if __name__ == &quot;__main__&quot; :

      shared_number = Value(&#39;i&#39;, 0) # int로 만들고, 초기값이 0
      p1 = Process(target=counter1, args=(shared_number,5000))
      p1.start()

      p2 = Process(target=counter2, args=(shared_number,5000))
      p2.start()

      p1.join()
      p2.join()

      print(&quot;finally, number is&quot;, shared_number.value)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/2680bf88-8149-4332-aaee-2bff36bbb013/image.png" alt="">
 -5000 +5000 하면 0이되야 맞지만, 동기화오류로 625가 나옴.</p>
<p> &lt;뮤텍스 락을 걸어준 코드&gt;</p>
<pre><code>    from multiprocessing import Process, Value, Lock
  # Value: 프로세스간의 값을 공유하게 만들고 싶을 때 사용하는 파이썬의 생성자함수

  def counter1(snum, cnt, lock): # snum:공유하는숫자, cnt:몇번연산을 수행할지
      lock.acquire() # 처음들어올 때 락을 걸고
      try:
          for i in range(cnt):
              snum.value += 1
      finally:
          lock.release() #문제없다면 release 해줌

  def counter2(snum, cnt, lock): # snum:공유하는숫자, cnt:몇번연산을 수행할지
      lock.acquire() # 처음들어올 때 락을 걸고
      try:
          for i in range(cnt):
              snum.value -= 1
      finally:
          lock.release() #문제없다면 release 해줌

  if __name__ == &quot;__main__&quot; :

      lock = Lock()
      shared_number = Value(&#39;i&#39;, 0) # int로 만들고, 초기값이 0
      p1 = Process(target=counter1, args=(shared_number,5000, lock))
      p1.start()

      p2 = Process(target=counter2, args=(shared_number,5000,lock))
      p2.start()

      p1.join()
      p2.join()

      print(&quot;finally, number is&quot;, shared_number.value)</code></pre><p>  &lt;실행결과&gt;
  <img src="https://velog.velcdn.com/images/bread_code/post/70271284-db56-45dd-9be3-02e548504104/image.png" alt=""></p>
<p>  p1이 실행할 때 p2 실행 안했고, p2 실행시 p1실행 안했음.</p>
<p> &lt;스레드에 대해 뮤텍스 락 제공&gt;</p>
<pre><code>  import threading
  from multiprocessing import Process, Value, Lock
  # Value: 프로세스간의 값을 공유하게 만들고 싶을 때 사용하는 파이썬의 생성자함수

  def counter1(snum, cnt, lock): # snum:공유하는숫자, cnt:몇번연산을 수행할지
      lock.acquire() # 처음들어올 때 락을 걸고
      try:
          for i in range(cnt):
              snum.value += 1
      finally:
          lock.release() #문제없다면 release 해줌

  def counter2(snum, cnt, lock): # snum:공유하는숫자, cnt:몇번연산을 수행할지
      lock.acquire() # 처음들어올 때 락을 걸고
      try:
          for i in range(cnt):
              snum.value -= 1
      finally:
          lock.release() #문제없다면 release 해줌

  if __name__ == &quot;__main__&quot; :

      lock = Lock()
      shared_number = Value(&#39;i&#39;, 0) # int로 만들고, 초기값이 0
      t1 = threading.Thread(target=counter1, args=(shared_number,10000, lock))
      t1.start()

      t2 = threading.Thread(target=counter2, args=(shared_number,10000,lock))
      t2.start()

      t1.join()
      t2.join()

      print(&quot;finally, number is&quot;, shared_number.value)</code></pre><p> &lt;실행결과&gt;
 <img src="https://velog.velcdn.com/images/bread_code/post/57495893-4d8a-4e3a-bece-63a8e337569f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day3 프로세스 통신과 동기화]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day3-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%ED%86%B5%EC%8B%A0%EA%B3%BC-%EB%8F%99%EA%B8%B0%ED%99%94</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day3-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%ED%86%B5%EC%8B%A0%EA%B3%BC-%EB%8F%99%EA%B8%B0%ED%99%94</guid>
            <pubDate>Fri, 05 Apr 2024 06:02:54 GMT</pubDate>
            <description><![CDATA[<h2 id="스케줄링-알고리즘">스케줄링 알고리즘</h2>
<h3 id="큐queue-자료구조">큐(Queue) 자료구조</h3>
<blockquote>
<p>준비상태에서 CPU를 기다리고 있는 프로세스들은 운영체제의 스케줄러에 의해 실행상태로 전환된다.
  실행상태의 프로세스들은 점유시간이 지나면 준비 상태가되고, 입출력 요청이 있는경우에 대기상태로   전환되기도 한다.
  이와같이 운영체제가 프로세스의 준비상태와 대기상태를 관리 할 때는 스케줄링Q라는 자료구조를 사   용한다.선입선출 형식의 자료구조이다.</p>
</blockquote>
<p>  <img src="https://velog.velcdn.com/images/bread_code/post/e5b2ea71-7715-45ce-95f2-ee9ab0656248/image.png" alt="">
&lt;출처: 유노코딩&gt;</p>
<p>  대표적으로 준비 큐 와 대기 큐가 존재한다. 준비큐는 CPU를 이용하기위한 프로세스들이 줄을 스기   위해 존재하는 큐, 대기큐는 입출력장치를 이용하기 위해 대기상태에 있는 프로세스들이 줄을 스기   위해 존재하는 큐이다. 큐에는 프로세스들의 컨트롤 블록들이 줄을 스게 되고 운영체제는 이를 보고   먼저 이용할 것을 실행한다.
  우선순위가 높은 것이 있을 경우 새치기를 허용한다.</p>
<h3 id="스케줄링-알고리즘-1">스케줄링 알고리즘</h3>
<p>  <strong>&lt; 스케줄링 알고리즘 시 고려사항들 &gt;</strong></p>
<ul>
<li><p>부하가 최소화되어야 한다</p>
</li>
<li><p>컴퓨팅 자원을 효율적으로 사용해야 한다</p>
</li>
<li><p>균형잡힌 스케줄링을 해야 한다</p>
</li>
<li><p>대기 및 응답 시간이 너무 길어서는 안 된다</p>
</li>
<li><p>*&lt;알고리즘의 종류들&gt;**</p>
</li>
<li><p>선입선출(First In First Out)</p>
</li>
<li><p>최단 작업 우선(Shortest Job First)</p>
</li>
<li><p>라운드 로빈(Round Robin)</p>
</li>
<li><p>우선순위 스케줄링(Priority Scheduling)</p>
</li>
</ul>
<h4 id="--선입선출">- 선입선출</h4>
<blockquote>
<p>준비큐에 삽입된 순서대로 프로세스들을 처리하는 가장 단순하고 직관적임. 먼저들어온 프로세스가 종료상태가 되어야만 다음 프로세스가 실행될 수 있음. 우선순위가 같다면 먼저 온 프로세스가 먼저, 실행시간이 짧든 길든 순서대로 처리해서 비효율적일 수 있음. </p>
</blockquote>
<h4 id="--최단-작업-우선">- 최단 작업 우선</h4>
<blockquote>
<p>프로세스의 실행시간이 짧은 프로세스들을 먼저 우선적으로 실행해줌. 그러나 프로세스의 실행시간을 정확히 예측하는 것이 거의 불가능하여 현실적이지  않음.</p>
</blockquote>
<h4 id="--라운드-로빈">- 라운드 로빈</h4>
<blockquote>
<p>선입선출 알고리즘에 타임슬라이스 라는 개념이 더해진 스케줄링 방식. 타임 슬라이스란 프로세스가 CPU를 사용할 수 있는 점유시간을 의미함. 정해진 타임슬라이스 만큼만 CPU를 점유하고 시간이 다 지나면, 컨텍스트 스위칭하는 방식임.</p>
</blockquote>
<h4 id="--우선순위-스케줄링">- 우선순위 스케줄링</h4>
<blockquote>
<p>각 프로세스마다 우선순위를 부여해서 우선순위가 높은 프로세스 먼저 실행하는 방식. 우선순위만 고려할 경우 우선순위가 낮은 프로세스가 배제되어 버리는 &#39;기아&#39;상태에 빠질 수 있음.</p>
</blockquote>
<h2 id="프로세스-간-통신">프로세스 간 통신</h2>
<p>  프로세스는 독립적으로 실행되지만 필요 시 다른 프로세스와 데이터를 주고받으며 통신하는 경우도   있음, 이를 프로세스 간 통신(Inter-Process Communication, IPC)라고 함.
  통신을 하려면, 통신의 각 주체가 만날 수 있는 일종의 창구(매개체)가 필요함, 프로세스 간 통신   에서도 마찬가지이다.</p>
<p>  프로세스가 만들어지면 독립적인 구조로서 각각의 영역을 가지고, 자신에게 할당된 메모리영역외에는   접근이 불가능해서 프로세스 간 통신은 쉽지 않다.</p>
<h3 id="메일슬롯-방식--파이프-방식">메일슬롯 방식 &amp; 파이프 방식</h3>
<ul>
<li><p><strong>메일슬롯 방식</strong></p>
<blockquote>
<p>메일슬롯 방식의 IPC는 데이터를 받기 위해서 프로세스가 우체통역할을 하는 객체를 마련하고      이를 통해 데이터를 주고받는 방식</p>
</blockquote>
<p>데이터를 받고 싶은 프로세스B(Receiver)는 밖에 우체통을 하나 마련, 이 우체통이 데이터 매    개체 역할을 하고 주소를 할당받은 하나의 객체임
데이터를 보내고싶은 프로세스A(Sender)는 이 주소를 통해 데이터를 보낼 수 있음</p>
<ul>
<li>서로 관련없는 프로세스간에 유용</li>
</ul>
</li>
<li><p><strong>파이프 방식</strong></p>
<blockquote>
<p>파이프 방식은 운영체제가 파이프 라는 것을 생성하여 그것으로 데이터를 주고받음. 
파이프 방식의 IPC는 익명 파이프 또는 네임드 파이프를 이용해 데이터를 주고받는다. 
익명 파이프는 서로 관계가 있는 프로세스간에 통신을 할 때 사용하는 단방향 파이프이고,
네임드 파이프는 프로세스 간에 양방향 통신을 할 때 사용하는 파이프이다.</p>
</blockquote>
</li>
<li><p>익명파이프는 서로 관련있는 부모, 자식 프로세스 사이에 유용</p>
</li>
</ul>
<h3 id="부모-자식간-프로세스-통신-실습-코드">부모 자식간 프로세스 통신 실습 코드</h3>
<pre><code> # 부모 자식간의 프로세스간 통신
  from multiprocessing import Process, Pipe
  import os

  def send(conn):
      print(f&#39;{os.getpid()}가 {os.getppid()}에게 데이터를 보낸다!&#39;)
      conn.send(&quot;Hello parent!&quot;)
      conn.close()

  if __name__ == &quot;__main__&quot; :
      parent, child = Pipe() #Pipe():생성자함수-&gt;튜플형태로 두개의 객체가 반환됨
      P = Process(target=send, args=(child,)) # 자식이 보내므로 args는 child
      P.start()
      print(&quot;기존 프로세스 아이디:&quot;, os.getpid())
      print(parent.recv()) #  부모는 받음 -&gt; hello parent 출력은 여기서 나옴
      P.join() # join():프로세스가 작업을 종료할때까지 기다림.</code></pre><p> &lt;실행결과&gt;
  <img src="https://velog.velcdn.com/images/bread_code/post/7a1b37e4-8fa7-4a52-8809-e445b89580c6/image.png" alt=""></p>
<p> &lt;실습코드2- 더 간단하게 통신:파일을 이용한 통신&gt;</p>
<pre><code>   # 파일을 이용한 데이터 통신, 두개의 프로세스가 하나의 파이을 번갈아 읽는 것.
  from multiprocessing import Process
  import os
  import time

  def writer() :
      print(f&#39;{os.getpid()}가 파일에 쓴다&#39;)
      with open(&#39;13.txt&#39;,&#39;w&#39;) as f: # w가 만드는 기능이기 때문에 13.txt가 없어도 실행시 만들어짐
          f.write(&quot;Hello~&quot;)

  def reader() :
      print(f&#39;{os.getpid()}가 파일을 읽는다&#39;)
      with open(&#39;13.txt&#39;,&#39;r&#39;) as f:
          print(f.read())

  if __name__ == &quot;__main__&quot; :
      p1 = Process(target=writer)
      p1.start()

      time.sleep(2)

      p2 = Process(target=reader)
      p2.start()

      p1.join()
      p2.join()</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/7ceac8fe-25c5-40fe-bb0a-3fe25f01a1d2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day2 CPU 스케줄링]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Fri, 05 Apr 2024 02:53:30 GMT</pubDate>
            <description><![CDATA[<h2 id="cpu-스케줄링">CPU 스케줄링</h2>
<h3 id="프로세스-스케줄링">프로세스 스케줄링</h3>
<p>   여러개의 프로세스들이 CPU의 점유시간에 나눠지기 때문에 여러개의 프로세스가 동시에 실행되는    것처럼 보이는 것임.
   CPU는 여러개의 프로세스를 빠르게 번갈아 실행하기 위해, 각 프로세스를 위해 일하는 시간을 조    금씩 나누어 배분함.
   프로세스의 CPU 점유순서 및 방법을 결정짓는 일을 <strong>&#39;프로세스 스케줄링&#39;</strong> 이라고 함.
   운영체제는 자신이 가지고있는 스케줄링 알고리즘을 적용해 자신이 가진 스케줄러 모듈을 운영함.</p>
<h3 id="프로세스-우선순위">프로세스 우선순위</h3>
<p>   CPU를 누구에게 먼저, 얼마 동안 할당해 줄지, 또 우선순위도 고려해야 한다.
   입출력 작업이 더 많은지, CPU이용시간이 더 많은지도 달라서 이에 따라 입출력 집중 프로세스      다, CPU집중 프로세스다 로 구분하여 부름
   프로세스 별로 요구하는 자원이 상이하기 때문에, 운영체제(스케줄러)가 모든 프로세스에 동일한    빈도로 CPU를 할당하는 것은 비합리적이다. 운영체제는 프로세스마다 우선순위를 부여하고 이를      기준으로 프로세스를 실행한다.</p>
<p>   but 우선순위가 같은 프로세스도 존재한다. 실습 예제를 통해 확인.</p>
<h3 id="실습코드">실습코드</h3>
<pre><code>  from multiprocessing import Process 
  import os
  import time

  def coke():
      while True:
          try:
              print(&quot;콜라 프로세스 아이디: &quot;, os.getpid())
              print(&quot;부모 프로세스 아이디: &quot;, os.getppid())
          except KeyboardInterrupt:
              break

  def cider():
      while True:
          try:
              print(&quot;사이다 프로세스 아이디: &quot;, os.getpid())
              print(&quot;부모 프로세스 아이디: &quot;, os.getppid())
          except KeyboardInterrupt:
              break

  def juice():
      while True:
          try:
              print(&quot;주스 프로세스 아이디: &quot;, os.getpid())
              print(&quot;부모 프로세스 아이디: &quot;, os.getppid())
          except KeyboardInterrupt:
              break

  if __name__ == &#39;__main__&#39; :
      print(&#39;07.py 프로세스 아이디 :&#39;, os.getpid())
      child1 = Process(target=coke)
      child1.start()
      time.sleep(0.5)
      child2 = Process(target=cider)
      child2.start()
      time.sleep(0.5)
      child3 = Process(target=juice)
      child3.start()
      time.sleep(0.5)</code></pre><p>  &lt;실행결과&gt;
  <img src="https://velog.velcdn.com/images/bread_code/post/00878054-f5e7-4578-ae37-711108573e78/image.png" alt=""></p>
<p>  31이 우선순위 번호를 의미하고 같은 번호가 있는 것 확인</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day2 스레드]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%EC%8A%A4%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%EC%8A%A4%EB%A0%88%EB%93%9C</guid>
            <pubDate>Fri, 05 Apr 2024 02:30:30 GMT</pubDate>
            <description><![CDATA[<h2 id="스레드의-이해">스레드의 이해</h2>
<h3 id="스레드thread">스레드(Thread)</h3>
<p>   컨텍스트 스위칭으로 인한 부하를 줄이기 위해서는 프로세스를 줄여야한다.
   프로세스의 구성원 중 스레드가 있는데 이는 프로세스가 실행하는 작업의 실행단위를 나타낸다.
   스레드는 프로세스 내에 1-10개 사이 존재 할 수 있다, 스레드들 끼리는 자신들이 속해있는 
   프로세스의 컨트롤블록인 코드영역, 데이터 영역, 힙영역을 공유하는데 구조적인 문제때문에 스택    영역은 한 스레드당 하나씩 가진다. 
   지역변수나 매개변수를 저장하는 영역이므로 작업마다 지역변수 영역을 따로 가져야 하기 때문에      스레드당 개별적을 할당된다.</p>
<p>   따라서 작업이 늘어나도 프로세스는 늘지 않고 스레드만 늘어나므로 부담이 적어 효율적이다.
   프로세스내에 여러개의 스레드가 있을 경우 프로세스 처럼 스레드 마다 개별적인 아이디가 존재하    고 프로세스 컨트롤 블록같은 스레드 컨트롤 블록도 존재한다.</p>
<h3 id="메모리-구조-관점에서-본-스레드-특징">메모리 구조 관점에서 본 스레드 특징</h3>
<ul>
<li><p>스레드와 프로세스의 차이 이해</p>
</li>
<li><p><em>스택영역만큼은 스레드마다 개별적으로 할당되는 이유*</em></p>
<blockquote>
<p>스택은 함수 호출시 전달되는 인자, 되돌아갈 주소값 과 지역변수등을 저장하기 위해 사용하는      메모리 공간이다. 스택은 먼저들어간 것이 가장 나중에 쓰인다. 따라서 이 메모리 공간이          독립적으로 할당되지 않으면 추가적인 실행흐름을 만들 수 없다.</p>
</blockquote>
</li>
<li><p><em>공유되는 영역들*</em></p>
<blockquote>
<p>스레드는 프로세스가 처리해야 할 작업을 수행하기 위해 존재하는 것이므로, 코드영역을 공유해      명령어에 접근할 수 있어야 하고, 
 명령어 실행 시 전역변수, 정적변수, 지역변수 등의 데이터에 접근해야 하므로 데이터 영역과      힙 영역도 공유해야한다.</p>
</blockquote>
<h3 id="실습코드">실습코드</h3>
<p>&lt;스레드 할당&gt;</p>
<pre><code># 스레드를 만들어 할당하는 방법
import threading
import os

def func():
  print(&#39;안녕, 나는 실험용으로 만든 대충함수야!&#39;)
  print(&#39;나의 프로세스 아이디 :&#39;, os.getpid())
  print(&#39;스레드 아이디 :&#39;, threading.get_native_id())

if __name__ == &#39;__main__&#39;:
  print(&#39;기존 프로세스 아이디&#39;, os.getpid())
  thread1 = threading.Thread(target=func)
  thread1.start()</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/7bbb3343-49db-42a3-9412-86928e13c697/image.png" alt=""></p>
<ul>
<li>스레드에 독립적인 아이디 할당됨 확인</li>
</ul>
<p>&lt;메인스레드, 하위스레드 동시 작동&gt;</p>
<pre><code>import threading
import os
import time

def something(word):
  while True:
      print(word)
      time.sleep(3)

if __name__ ==  &#39;__main__&#39; :
  print(&#39;기존 프로세스 아이디 :&#39;, os.getpid())
  t = threading.Thread(target=something, args=(&#39;happy&#39;,)) #word에 전달할때 args써서 튜플형태로 전달
  t.daemon = True # daemon 스레드는 자기에게 일을시킨 스레드에 메인기능이 끝나면 같이 끝난다는 속성
  t.start()
  print(&#39;메인 스레드에서 반복문 시작&#39;)
  while True:
      try:
          print(&#39;daily...&#39;)
          time.sleep(1)
      except KeyboardInterrupt:
          print(&#39;good bye~&#39;)
          break

# 현재 메인스레드와 하위스레드 두개를 가지고 있는 것임/ daily는 메인스레드, happy는 하위스레드</code></pre><p>&lt;실행결과&gt;</p>
<p><img src="https://velog.velcdn.com/images/bread_code/post/c94fb6b9-f09c-46c1-99e3-d6d420cbb4c9/image.png" alt=""></p>
</li>
</ul>
<p>현재 메인스레드와 하위스레드 두개를 가지고 있고 1초에1번 daily는 메인스레드, 3초에 한번happy는 하위스레드 에 할당되 있음.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day2 프로세스 생성]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Thu, 04 Apr 2024 08:20:27 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-프로세스-생성">📌 프로세스 생성</h2>
<ul>
<li><p>프로그램 실행 시, 운영체제는 코드영역과 데이터영역을 메인메모리에 올리고 
빈 스택과 빈 힙을 만들어 공간을 확보한다. 운영체제의 핵심체제 중 하나인 메모리관리작업을 통    해 이뤄지고 이는 시스템에게는 상당히 부담을 주는 일이다.</p>
</li>
<li><p>프로그램이 실행되면 프로세스가 되었다고 보고 이것을 프로세스가 생성되었다고 한다. 프로세스      가 생성되면 컨트롤블록을 만들어서 프로세스 정보, 아이디 등을 초기화하게 됨.</p>
</li>
</ul>
<h4 id="최초의-프로세스">최초의 프로세스</h4>
<blockquote>
<p>최초의 프로세스를 제외한 프로세스들은 최초의 프로세스를 복사해서 이뤄진다. 
  이 첫번째 프로세스가 부모 프로세스, 이를 복사해 만든 프로세스를 자식 프로세스라고 하고
  이때 부모프로세스를 복사하는 시스템함수를 fork()라고 함.
  새로운 프로세스를 생성하지 않고 기존 프로세스를 복사해서 만드는 것은 시스템의 과부하를
  방지 함</p>
</blockquote>
<blockquote>
<p>exec():코드영역과 데이터영역을 새롭게 덮어 씌어주는 함수
   를 이용해 자식프로세스들은 데이터를 변경하여 새롭게 생성된 목적에 맞는 일을 독립적으로 
   수행한다.</p>
</blockquote>
<h3 id="실습-코드">실습 코드</h3>
<ul>
<li>멀티프로세스</li>
</ul>
<p>&lt;예제 5번&gt;</p>
<pre><code>from multiprocessing import Process 
# multiprocessing : 멀티프로세싱 프로그램을 하고 싶을 때 사용하는 패키지
# Process : 자식 프로세스를 생성할 때 사용하는 객체, 클래스 임.
import os

def func():
    print(&#39;안녕,  나는 실험용으로 대충 만들어본 함수야!&#39;)
    print(&#39;나의 프로세스 아이디:&#39;, os.getpid())
    print(&#39;나의 부모 프로세스 아이디:&#39;, os.getppid())

if __name__ == &#39;__main__&#39; :
    print(&#39;05.py 프로세스 아이디 :&#39;, os.getpid())
    child = Process(target=func).start()

# 05.py가 부모프로세스가 되고 하위프로세스에게 func한수를 시킬거야</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/b1893e55-3703-4e3d-af10-116210c83360/image.png" alt=""></p>
<p>&lt;예제 6번&gt;</p>
<pre><code>from multiprocessing import Process 
import os
import time


def func():
    print(&#39;안녕,  나는 실험용으로 대충 만들어본 함수야!&#39;)
    print(&#39;나의 프로세스 아이디:&#39;, os.getpid())
    print(&#39;나의 부모 프로세스 아이디:&#39;, os.getppid())

if __name__ == &#39;__main__&#39; :
    print(&#39;06.py 프로세스 아이디 :&#39;, os.getpid())
    child1 = Process(target=func)
    child1.start()
    time.sleep(0.5)
    child2 = Process(target=func)
    child2.start()
    time.sleep(0.5)
    child3 = Process(target=func)
    child3.start()
    time.sleep(0.5)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/939ed9d7-4915-48c1-891b-3a182953db00/image.png" alt=""></p>
<p>&lt;예제 7번&gt;</p>
<pre><code>from multiprocessing import Process 
import os
import time

def coke():
    print(&quot;콜라 프로세스 아이디: &quot;, os.getpid())
    print(&quot;부모 프로세스 아이디: &quot;, os.getppid())

def cider():
    print(&quot;사이다 프로세스 아이디: &quot;, os.getpid())
    print(&quot;부모 프로세스 아이디: &quot;, os.getppid())

def juice():
    print(&quot;주스 프로세스 아이디: &quot;, os.getpid())
    print(&quot;부모 프로세스 아이디: &quot;, os.getppid())

if __name__ == &#39;__main__&#39; :
    print(&#39;07.py 프로세스 아이디 :&#39;, os.getpid())
    child1 = Process(target=coke)
    child1.start()
    time.sleep(0.5)
    child2 = Process(target=cider)
    child2.start()
    time.sleep(0.5)
    child3 = Process(target=juice)
    child3.start()
    time.sleep(0.5)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/2b5ed680-ed0b-48f4-97c0-b2530c5626ca/image.png" alt=""></p>
<p>&lt;과제 실습 코드&gt;</p>
<pre><code># 내 파이썬 프로그램의 이름을 알아보자.
# psutil로 지금 돌아가고 있는 프로세스를 싹 다 조회한다
# 조회하다가 08.py와 프로세스 아이디가 일치하는 아이디를 발견하면 프로세스 이름을 출력한다.
import psutil 
import os


if __name__ == &#39;__main__&#39; :
    print(&#39;08.py 프로세스 아이디 :&#39;, os.getpid())

for proc in psutil.process_iter():
    ps_name = proc.name()
    if os.getpid() ==  proc.pid:
        print(f&#39;08.py의 프로세스 이름은: {ps_name}&#39;, f&#39;아이디는 : {proc.pid}&#39;)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/63e2e2c2-50d0-4235-8903-8e48b7aa65d3/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day2 프로세스 관리]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Thu, 04 Apr 2024 07:20:57 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-컨텍스트-스위칭">📌 컨텍스트 스위칭</h2>
<p>  프로세스들이 상태를 바꿔가며 실행될 때 필요한 정보를 관리하는 방법</p>
<p>  멀티프로세스를 관리하는 운영체제는 바쁘다. 운영체제는 어떻게 효율적으로 관리 할까.</p>
<p>  <img src="https://velog.velcdn.com/images/bread_code/post/e6fc505d-92cb-436c-9425-656ed233a260/image.png" alt=""></p>
<h3 id="컨텍스트-스위칭">컨텍스트 스위칭</h3>
<blockquote>
<p>프로세스 실행 중 다른 프로세스를 실행하기 위해 
  실행중인 A프로세스를 저장하고 다른 B프로세스 데이테로 교체하는 작업</p>
</blockquote>
<p> A가 실행되다가 점유시간이 지나면 프로세스 컨트롤 블록에 현재 CPU의 레지스터 값을 싹 저장하고 프로세스A는 준비상태로 되게 되고, </p>
<p> 프로세스 B가 진행상태로 변경됨, 이때 프로세스B도 프로세스 컨트롤 블록에 백업해둔 정보를 이용해 레지스터에 등록함. 프로세스B의 점유시간도 초과가 되면 다시 프로세스 A가 진행상태가 됨.
 메모리에 있는 모든 프로세스들은 컨텍스트 스위칭이라는 작업을 통해 실행되게 됨.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day2 프로세스]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</guid>
            <pubDate>Thu, 04 Apr 2024 06:45:37 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-프로세스">📌 프로세스</h2>
<blockquote>
<ul>
<li>프로세스란 &#39;실행 중인 프로그램&#39;을 뜻함, 프로세스는 메인메모리, 운영체제의 CPU 스케줄링, 키보드나 마우스 같은 입출력장치등 컴퓨터의 리소스를 사용하는 활동적인 존재로 잠만자고 있는 프로그램이랑 다르다.</li>
</ul>
</blockquote>
<h3 id="📌-프로세스-구조">📌 프로세스 구조</h3>
<p>  프로세스는 운영체제가 관리하는 하나의 객체라고 할 수 있고 구조를 가지고 있다.</p>
<ul>
<li><p>명령어가 담긴 코드영역
프로세스가 실행하는 코드, 즉 명령어 집합이 저장되어 있는 영역</p>
</li>
<li><p>전역변수 등이 담긴 데이터 영역
코드에서 여러 변수들을 호출해서 사용하는데 이 중 전역변수나 static변수 등이 저장되 있는 영역</p>
</li>
<li><p>지역변수 등이 담긴 스택 영역
지역변수나 함수의 매개변수 같은 휘발성 변수가 저장되어 있는 영역</p>
</li>
<li><p>동적 메모리 할당을 위한 힙 영역
프로세스가 동적으로 메모리를 할당하는 경우에 사용하는 영역</p>
<h3 id="📌-레지스터">📌 레지스터</h3>
<p><img src="https://velog.velcdn.com/images/bread_code/post/762bf324-8c95-4e94-81a1-d9d05ad6abfd/image.png" alt="">
&lt;출처:유노코딩&gt;</p>
<p>프로세스의 구성요소는 아니지만 프로세스 관리 시 무척 중요한 역할을 하는 레지스터
프로그램의 실행을 위해서는 절대적으로 레지스터가 필요하다</p>
<p>CPU가 명령을 실행 할 때마다 사용해야 할 다양한 유형의 데이터들이 레지스터에 임시적으로 저    장되는 과정을 반복해야하고, 
CPU를 구성하는 레지스터들은 현재 실행중인 프로세스들을 위한 데이터들로 채워지게 된다.
따라서 레지스터의 상태들도 프로세스의 일부로 포함시켜 말할 수 있다.</p>
</li>
</ul>
<h3 id="📌-vsc-실습-예제-코드">📌 VSC 실습 예제 코드</h3>
<p>  &lt;예제 2번&gt;</p>
<pre><code>  # 파이썬 프로그램도 프로세스가 된다

    import os

    print(&#39;파이썬 코드 실행 중! 실행 중인 프로세스의 아이디는 :&#39;, os.getpid()) 
    # 운엥체제는 프로세스ID를 만들어서 프로세스가 몇번인지 참조해가며 관리함
    # getpid: 그것을 확인할 수 있게 해주는 코드
    # =&gt; 프로세스에는 ID가 할당된다.</code></pre><p>  &lt;실행 결과&gt;
  <img src="https://velog.velcdn.com/images/bread_code/post/77ab0844-3dd7-42db-8375-06f491fbd1bf/image.png" alt=""></p>
<p>  =&gt; 프로세스에는 ID가 할당된다.</p>
<p>  &lt;예제 3번&gt;</p>
<pre><code> # 내 운영체제 안에서 프로세스를 조회할 수 있는 코드
    # pip install psutil
    # 내 컴퓨터에서 돌아가는 프로세스 조회하기

    import psutil

    for proc in psutil.process_iter():
        ps_name = proc.name()
          if &quot;Chrome&quot; in ps_name : # Chrome 이 들어간 프로세스 이름만 나오도록 설정
          print(ps_name, proc.pid) # psutil 모듈도 proc.id 받을 수 있음</code></pre><p>  &lt;실행결과&gt;
  <img src="https://velog.velcdn.com/images/bread_code/post/75df89c3-092b-4aef-928e-fb40adb245c9/image.png" alt=""></p>
<h2 id="📌-프로세스-상태">📌 프로세스 상태</h2>
<p> 프로세스는 어떻게 관리되는가</p>
<h3 id="process-control-block">Process Control Block</h3>
<p>  컴퓨터에서는 여러개의 프로그램을 실행시켜두는 경우가 많다. CPU는 이 작업들을 동시에 하는가?
  아니다. CPU는 한 번에 하나의 연산만 수행 할 수 있다. 따라서 CPU는 여러 개의 프로세스를 동   시에 실행하지 않고, 빠르게 번갈아 가며 실행한다. 
  운영체제는 빠르게 번갈아 실행되는 프로세스의 실행 순서를 관리하고, 프로세스마다 자원을 분배하   고 이에 PCB(Process Control Block)을 이용한다.
  PCB, 프로세스 컨트롤 블록은 프로세스와 관련된 정보를 저장하는 자료구조이다. 프로세스 컨트롤   블록에는 프로세스를 식별하기 위해 필요한 정보들이 저장된다.
  =&gt; 프로세스 ID, 레지스터 데이터, 스케줄링 정보, 상태 등이 저장된다.
  =&gt; PCB는 프로세스가 생성 될 때마다 같이 생성되는 하나의 객체인 것</p>
<p>  <img src="https://velog.velcdn.com/images/bread_code/post/d4390965-7206-4acf-ae8d-baa795d6efe6/image.png" alt="">
&lt;출처: 유노코딩&gt;
  -- 프로세스의 상태변화를 나타낸 그림</p>
<p>  운영체제는 CPU가 여러개의 프로세스를 번갈아 실행할 수 있도록 해야한다. 프로세스들은 상황에   따라 서로다른 상태 정보를 가짐.</p>
<ul>
<li><p>생성 </p>
<blockquote>
<p>보조기억장치에 잠들어 있던 프로그램을 깨워 메인메모리에 올려 실행을 시키면 그때부터 프로세     스가 등장하는 것 이 과정을 생성이라고 함.</p>
</blockquote>
</li>
<li><p>준비(ready)</p>
<blockquote>
<p>프로세스는 생성과 동시에 ready, 대기 상태가 된다. CPU에 의해 실행되기를 기다리는 상태.</p>
</blockquote>
</li>
<li><p>실행(Running)</p>
<blockquote>
<p>CPU에 의해 실행되는 상태, 한가지 프로세스만 실행하는 것이 아니라 프로세스의 중요도, 우선     순위에 따라 준비, 실행이 교차로 일어남. </p>
</blockquote>
</li>
<li><p>대기(Blocked)</p>
<blockquote>
<p>실행과 준비를 교차하는 중 출력관련 작업요청이 들어와서 잠시 작업을 멈추는 상태</p>
</blockquote>
<p>=&gt; 준비상태에 있는 프로세스는 언제든 다시 실행 상태로 될 수 있지만 대기상태에 있는 프로세스는 대기상태로 된 이유가 사라져서 다시 준비 상태로 되야 실행될 수 있다.</p>
</li>
<li><p>종료</p>
<blockquote>
<p>준비, 실행, 대기를 반복하다가 자기 할일을 마치게 되면 프로세스가 종료되고 프로세스가 사라지게 됨. 프로세스의 소멸. 잠든 프로그램이 되는 것.</p>
</blockquote>
<h3 id="프로세스-계층">프로세스 계층</h3>
<p><img src="https://velog.velcdn.com/images/bread_code/post/ba54548a-90cf-49f8-a508-a377c2f6322f/image.png" alt="">
&lt;출처:유노코딩&gt;</p>
<p>실행도중 시스템호출을 통해 다른 프로세스를 생성할 수 있음. 프로세스가 프로세스를 낳는 것.
처음 프로세스를 부모프로세스, 거기서 나온 프로세스는 자식프로세스 이고 이는 <strong>서로 독립적인 영   역</strong>을 가진다.
이 프로세스 족보를 프로세스 계층이라고 표현함.</p>
</li>
</ul>
<h3 id="프로세스-계층이-존재하는-것을-확인하는-실습-예제-코드">프로세스 계층이 존재하는 것을 확인하는 실습 예제 코드</h3>
<p>  &lt;실습코드&gt;</p>
<pre><code>  import psutil

  for proc in psutil.process_iter():
      ps_name = proc.name()

      if &quot;Chrome&quot; in ps_name :
          child = proc.children()
          print(ps_name, proc.status(), proc.parent(), child)

          if child :
              print(f&#39;{ps_name}의 자식 프로세스&#39;, child)</code></pre><p>  &lt;실행결과&gt;
  <img src="https://velog.velcdn.com/images/bread_code/post/2c9493c0-e953-4525-9e98-cae91cb3c7ae/image.png" alt=""></p>
<p>  =&gt; 자식 프로세스가 많이 나온 부모 Chrome이 본체인 것.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day1 인터럽트]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day1-%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day1-%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8</guid>
            <pubDate>Wed, 03 Apr 2024 09:02:51 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-인터럽트">📌 인터럽트</h2>
<h3 id="cpu-인터럽트">CPU 인터럽트</h3>
<ul>
<li><p>CPU가 어떤 작업을 수행하고 있을 때 CPU의 작업을 방해하는 신호를 말함.</p>
</li>
<li><p>방해라고 안좋은 신호인 것만이 아니라 먼저 수행해야 할 명령어가 있음을 알려주는 신호이기도 함.</p>
</li>
<li><p>정상적으로 수행할 수 없는 명령어가 입력되면 CPU는 인터럽트를 발생시키고, 이때의 인터럽트를 
동기인터럽트, &#39;예외&#39;라고 한다. 연산시예외, 입력예외, 파일못찾는 예외 등 코드를 짤때 발생 하는   여러 예외들이 모두 CPU 인터럽트이다.</p>
</li>
</ul>
<h3 id="하드웨어비동기-인터럽트">하드웨어(비동기) 인터럽트</h3>
<ul>
<li>입출력장치(하드웨어)로부터 발생하는 인터럽트는 &#39;비동기 인터럽트&#39;라고 함.</li>
</ul>
<h3 id="인터럽트-핸들링">인터럽트 핸들링</h3>
<ul>
<li>인터럽트가 발생하면, 인터럽트에 대응하는 무언가가 동작해야 한다.
이를 &#39;인터럽트 서비스 루틴&#39;이라 한다.
<strong>인터럽트 서비스 루틴</strong>은 인터럽트를 처리하기 위해 특정 인터럽트 신호에 대해 미리 정의되     어 있는 프로그램 또는 함수이다.
인터럽트가 발생하면 하던동작을 잠시 멈추고 인터럽트 서비스 루틴이 작동한 후 다시 실행하는     것인데 그래서 인터럽트 핸들링이라고도 불린다.</li>
</ul>
<h3 id="📍-인터럽트-예제">📍 인터럽트 예제</h3>
<pre><code># 인터럽트 예제

# 두개의 모듈 사용
import time # 시간을 제어
import signal # 신호를 처리, 비동기 이벤트에 대한 핸들러 모듈 
              # - 키보드,마우스 등의 인터럽트 발생시 대응 할 수 있게, 대응하여 인터럽트 핸들러를 만들 수 있게 해줌.

def handler(signum, frame) : # signum: 처음으로 인터럽트의 유형 번호를 받게됨 / frame: 메모리 영역 중 정보를 수행하는 역할
    print(&#39;키보드 인터럽트 감지&#39;)
    print(&#39;신호 번호:&#39;, signum)
    print(&#39;스텍 프레임:&#39;, frame)
    exit() # 강제 종료 함수: 인터럽트 발생 시 강제종료

signal.signal(signal.SIGINT, handler) # SIGINT: 키보드인터럽트 상수

while True:
    print(&#39;5초 간격으로 츨력 중...&#39;)  # 5초마다 출력 반복, 이때 키보드 인터럽트 발생 시 handler함수만 동작하게 됨.
    time.sleep(5)</code></pre><p>&lt;실행결과&gt;
<img src="https://velog.velcdn.com/images/bread_code/post/222ce8bf-cdb2-49f7-a169-aab945bc4d82/image.png" alt=""></p>
<p>=&gt; Signal 모듈을 이용해 인터럽트를 처리하는 파이썬에서의 패턴 확인
운영체제에서 인터럽트에 대한 정의를 미리 해놓았기 때문에 이러한 인터럽트 처리가 가능 한 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Day1 프로그램의 실행과정]]></title>
            <link>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day1-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%98-%EC%8B%A4%ED%96%89%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@bread_code/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Day1-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%98-%EC%8B%A4%ED%96%89%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Wed, 03 Apr 2024 08:12:23 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-프로그램의-실행과정">📌 프로그램의 실행과정</h2>
<p><img src="https://velog.velcdn.com/images/bread_code/post/ef867be9-6827-483d-b079-7b05936cd00f/image.png" alt="">
&lt;출처:유노코딩&gt;</p>
<h4 id="--프로그래밍-언어프로그램코드를-이용해서-코드를-짜고-이를-컴파일함">-&gt; 프로그래밍 언어(프로그램코드)를 이용해서 코드를 짜고 이를 컴파일함</h4>
<h4 id="--컴파일러는-if-나-while등의-인간친화적인-문법으로-만들어진-프로그래밍언어-코드를-기계-즉-컴퓨터친화적인-어셈블리-프로그램어셈블리코드으로-변경해줌">-&gt; 컴파일러는 if 나 while등의 인간친화적인 문법으로 만들어진 프로그래밍언어 코드를 기계 즉 컴퓨터친화적인 어셈블리 프로그램(어셈블리코드)으로 변경해줌</h4>
<h4 id="--컴파일러에-의해-번역된-어셈블리-코드는-컴퓨터에-의해-실행되기-앞서-다시-바이너리-코드1과0----만으로-구성된-코드로-번역되기도-함-컴퓨터는-오로지-1과-0-바이너리-코드만-이해할-수-있기----때문">-&gt; 컴파일러에 의해 번역된 어셈블리 코드는 컴퓨터에 의해 실행되기 앞서 다시 바이너리 코드(1과0    만으로 구성된 코드)로 번역되기도 함. 컴퓨터는 오로지 1과 0 바이너리 코드만 이해할 수 있기    때문</h4>
<p><img src="https://velog.velcdn.com/images/bread_code/post/ea426b47-7fd8-4895-96b3-b4beb494ee48/image.png" alt="">
&lt;출처:유노코딩&gt;</p>
<p>-&gt; <strong>실행파일이 만들어지고 나면 일반적으로 하드디스크같은 보조메모리에 저장됨.</strong></p>
<p>-&gt; <strong>실행하면 이것이 메인 메모리에 올라가게 되고, CPU에 의해 차례대로 실행되기 시작함.</strong> </p>
<p>-&gt; <strong>메인메모리에 올라간 명령어들은 CPU에 의해 순차적으로 실행이 됨. **<em>메인 메모리에서 CPU      로 순차적으로 하나씩 이동한 다음 실행</em></strong> 됨.**</p>
<ul>
<li><p>이때 <strong><em>진행되는 단계는 3가지 단계</em></strong> 로 구분</p>
<p><strong>1. Fetch</strong></p>
<p>  메모리상에 존재하는 명령어를 CPU로 가져오는 작업, 이렇게 이동된 명령어를 저장하기 이해       사용되는 것이 register이다(instruction register)가 이 작업을 수행한다.</p>
<p><strong>2. Decode</strong></p>
<p>  가져다놓은 명령어를 CPU가 해석하는 단계, CU가 이 역할을 담당한다.</p>
<p><strong>3. Execution</strong></p>
<p>  해석된 명령어의 명령대로 CPU가 작업을 수행하는 단계, ALU가 이 역할을 담당한다.</p>
<p>=&gt; 이는 컴퓨터의 구성요소들이 데이터를 잘 주고받을 수 있어야 실행될 수 있는 단계들이다.</p>
</li>
</ul>
<h3 id="🧷-데이터-이동은-시스템-버스">🧷 데이터 이동은 시스템 버스</h3>
<p><img src="https://velog.velcdn.com/images/bread_code/post/d9462cd0-8007-4c53-85a8-0d1bc29403f2/image.png" alt="">
&lt;출처:유노코딩&gt;</p>
<ul>
<li><strong>데이터 버스: 데이터 이동을 위헤 필요한 버스</strong></li>
<li><strong>컨트롤 버스: CPU가 원하는 바를 메모리에 전달하기 위한 버스, 메모리에 명령어 전달</strong></li>
<li><strong>어드레스 버스: 주소값을 이동하기 위해 필요한 버스, 주소값을 참조하기 위해 사용</strong></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>