Prj2-Definition.pdf

‫ﺑﻪ ﻧﺎﻡ ﺧﺪﺍ‬
‫ﭘﺮﻭﮊﻩﻱ ﺩﻭﻡ ﺩﺭﺱ ﺳﻴﺴﺘﻢﻋﺎﻣﻞ‬
‫ﮐﻨﺘﺮﻝ ﻫﻤﺮﻭﻧﺪﻱ ﭘﺮﺩﺍﺯﻩﻫﺎ‬
‫ﺷﺮﺡ ‪Semaphore API‬‬
‫ﭼﻮﻥ ﺩﺭ ﺍﻳﻦ ﭘﺮﻭﮊﻩ ﻧﻴﺎﺯ ﺑﻪ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺳﻤﺎﻓﻮﺭﻫﺎ ﺩﺍﺭﻳﺪ ﻭ ‪ system call‬ﻫﺎﻱ ‪ Linux‬ﮐﻪ ﺑـﺮﺍﻱ ﮐـﺎﺭ ﺑـﺎ ﺳـﻤﺎﻓﻮﺭﻫﺎ ﺗﻮﻟﻴـﺪ‬
‫ﺷﺪﻩﺍﻧﺪ ﺩﺍﺭﺍﻱ ﺟﺰﺋﻴﺎﺕ ﺯﻳﺎﺩﻱ ﻫﺴﺘﻨﺪ‪ ،‬ﻳﮏ ‪ API‬ﺳﺎﺩﻩﺗﺮ ﺑـﺮﺍﻱ ﮐـﺎﺭ ﺑـﺎ ﺳـﻤﺎﻓﻮﺭﻫﺎ ﺩﺭ ﻗﺎﻟـﺐ ﻓﺎﻳﻠﻬـﺎﻱ ‪ Sem.h‬ﻭ ‪Sem.c‬‬
‫ﺑﺮﺍﻱ ﺷﻤﺎ ﺗﻮﻟﻴﺪ ﺷﺪﻩ ﻭ ﺑﺎﻳﺪ ﺍﺯ ﺁﻥ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪ .‬ﺷﺮﺡ ﺗﻮﺍﺑﻌﻲ ﮐﻪ ﺍﻳﻦ ‪ API‬ﺩﺭ ﺍﺧﺘﻴﺎﺭ ﺷﻤﺎ ﻣﻲﮔﺬﺍﺭﺩ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬
‫)‪int init_semaphores(int nsems‬‬
‫ﺑﺮﺍﻱ ﮐﺎﺭ ﺑﺎ ﺳﻤﺎﻓﻮﺭﻫﺎ ﺑﺎﻳﺪ ﺍﺑﺘﺪﺍ ﺍﻳﻦ ﺗﺎﺑﻊ ﺭﺍ ﻓﺮﺍﺧﻮﺍﻧﻲ ﮐﻨﻴﺪ‪ nsems .‬ﺗﻌﺪﺍﺩ ﺳﻤﺎﻓﻮﺭﻫﺎﻳﻲ ﺍﺳﺖ ﮐﻪ ﺩﺭ ﺑﺮﻧﺎﻣـﻪ ﺧـﻮﺩ ﺑـﻪ ﺁﻧﻬـﺎ‬
‫ﻧﻴﺎﺯ ﺩﺍﺭﻳﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫﺪ ﭘﻴﺎﻡ ﻣﻨﺎﺳﺐ ﭼﺎﭖ ﺷـﺪﻩ ﻭ ﺧﺮﻭﺟـﻲ ‪ -1‬ﺧﻮﺍﻫـﺪ ﺑـﻮﺩ ﻭ ﺩﺭ ﻏﻴـﺮ ﺍﻳـﻦ ﺻـﻮﺭﺕ‬
‫ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪ .‬ﭘﺲ ﺍﺯ ﺍﺟﺮﺍﻱ ﺍﻳﻦ ﺗﺎﺑﻊ ﺳﻤﺎﻓﻮﺭﻫﺎﻳﻲ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ 0‬ﺗﺎ ‪ nsems-1‬ﺑﺮﺍﻱ ﺷﻤﺎ ﺗﻮﻟﻴﺪ ﻣﻴﺸﻮﻧﺪ‪.‬‬
‫)‪int sem_init(int snum, int value‬‬
‫ﺍﺯ ﺍﻳﻦ ﺗﺎﺑﻊ ﺑﺮﺍﻱ ﻣﻘﺪﺍﺭ ﺍﻭﻟﻴﻪ ﺩﺍﺩﻥ ﺑﻪ ﺳﻤﺎﻓﻮﺭﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪ snum .‬ﺷﻤﺎﺭﻩ ﺳﻤﺎﻓﻮﺭﻱ ﺍﺳﺖ ﮐﻪ ﻣﻲﺧﻮﺍﻫﻴـﺪ ﺑـﻪ ﺁﻥ ﻣﻘـﺪﺍﺭ‬
‫ﺍﻭﻟﻴﻪ ﺩﻫﻴﺪ ﻭ ‪ value‬ﻣﻘﺪﺍﺭ ﺍﻭﻟﻴﻪ ﻣﻮﺭﺩ ﻧﻈﺮ ﻣﻲﺑﺎﺷﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫﺪ ﭘﻴﺎﻡ ﻣﻨﺎﺳﺐ ﭼﺎﭖ ﺷﺪﻩ ﻭ ﺧﺮﻭﺟﻲ ‪-1‬‬
‫ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﺩﺭ ﻏﻴﺮ ﺍﻳﻦ ﺻﻮﺭﺕ ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪.‬‬
‫)‪int sem_signal(int snum‬‬
‫ﺩﺳﺘﻮﺭ ‪ Signal‬ﺭﺍ ﺑﺮ ﺭﻭﻱ ﺳﻤﺎﻓﻮﺭ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ snum‬ﺍﺟﺮﺍ ﻣﻲﮐﻨﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫﺪ ﭘﻴﺎﻡ ﻣﻨﺎﺳﺐ ﭼـﺎﭖ ﺷـﺪﻩ‬
‫ﻭ ﺧﺮﻭﺟﻲ ‪ -1‬ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﺩﺭ ﻏﻴﺮ ﺍﻳﻦ ﺻﻮﺭﺕ ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪.‬‬
‫)‪int sem_wait(int snum‬‬
‫ﺩﺳﺘﻮﺭ ‪ Wait‬ﺭﺍ ﺑﺮ ﺭﻭﻱ ﺳﻤﺎﻓﻮﺭ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ snum‬ﺍﺟﺮﺍ ﻣﻲﮐﻨﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫﺪ ﭘﻴﺎﻡ ﻣﻨﺎﺳﺐ ﭼـﺎﭖ ﺷـﺪﻩ ﻭ‬
‫ﺧﺮﻭﺟﻲ ‪ -1‬ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﺩﺭ ﻏﻴﺮ ﺍﻳﻦ ﺻﻮﺭﺕ ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪.‬‬
‫)(‪int clean_semaphores‬‬
‫ﺗﻤﺎﻣﻲ ﺳﻤﺎﻓﻮﺭﻫﺎ ﺭﺍ ﺁﺯﺍﺩ ﻣﻲﮐﻨﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫﺪ ﭘﻴﺎﻡ ﻣﻨﺎﺳﺐ ﭼﺎﭖ ﺷﺪﻩ ﻭ ﺧﺮﻭﺟﻲ ‪ -1‬ﺧﻮﺍﻫـﺪ ﺑـﻮﺩ ﻭ ﺩﺭ‬
‫ﻏﻴﺮ ﺍﻳﻦ ﺻﻮﺭﺕ ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪.‬‬
‫ﺷﺮﺡ ‪Shared Integers API‬‬
‫ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﺍﻳﻨﮑﻪ ﻣﻤﮑﻦ ﺍﺳﺖ ﺩﺭ ﺣﻴﻦ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﭘﺮﻭﮊﻩ ﻧﻴﺎﺯ ﺑﻪ ﻣﺘﻐﻴﺮﻫﺎﻱ ﻣﺸﺘﺮﮎ ﺑﻴﻦ ﭘﺮﺩﺍﺯﻩﻫﺎﻱ ﺧﻮﺩ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ ،‬ﻳـﮏ‬
‫‪ API‬ﺳﺎﺩﻩ ﺩﺭ ﻗﺎﻟﺐ ﻓﺎﻳﻠﻬﺎﻱ ‪ SHI.h‬ﻭ ‪ SHI.c‬ﺑﺮﺍﻱ ﺷﻤﺎ ﺗﻮﻟﻴﺪ ﺷﺪﻩ ﻭ ﻣﻲﺗﻮﺍﻧﻴﺪ ﺍﺯ ﺁﻥ ﺑﺮﺍﻱ ﺩﺍﺷﺘﻦ ﻣﺘﻐﻴﺮﻫﺎﻱ ﻣﺸـﺘﺮﮎ ﺍﺯ‬
‫ﻧﻮﻉ ‪ int‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ )ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﻧﻴﺎﺯ ﺑﻪ ﺩﺍﺷﺘﻦ ﻣﺘﻐﻴﺮﻫﺎﻱ ﻣﺸﺘﺮﮐﻲ ﺑﺎ ﻧﻮﻉ ﺩﻳﮕﺮ ﺩﺍﺭﻳـﺪ ﻣـﻲﺗﻮﺍﻧﻴـﺪ ﻣﺴـﺘﻘﻴﻤﺎ ﺍﺯ ﺍﻣﮑﺎﻧـﺎﺕ‬
‫‪ Shared Memory‬ﺩﺭ ‪ Linux‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ(‪ .‬ﺷﺮﺡ ﺗﻮﺍﺑﻌﻲ ﮐﻪ ﺍﻳﻦ ‪ API‬ﺩﺭ ﺍﺧﺘﻴﺎﺭ ﺷـﻤﺎ ﻣـﻲﮔـﺬﺍﺭﺩ ﺑـﻪ ﺻـﻮﺭﺕ ﺯﻳـﺮ‬
‫ﺍﺳﺖ‪:‬‬
‫)‪int init_integers(int nints‬‬
‫ﺑﺮﺍﻱ ﮐﺎﺭ ﺑﺎ ﺍﻋﺪﺍﺩ ﺻﺤﻴﺢ ﻣﺸﺘﺮﮎ ﺑﺎﻳﺪ ﺍﺑﺘﺪﺍ ﺍﻳﻦ ﺗﺎﺑﻊ ﺭﺍ ﻓﺮﺍﺧﻮﺍﻧﻲ ﮐﻨﻴﺪ‪ nints .‬ﺗﻌﺪﺍﺩ ﺍﻋﺪﺍﺩ ﺻﺤﻴﺢ ﻣﺸـﺘﺮﮐﻲ ﺍﺳـﺖ ﮐـﻪ ﺩﺭ‬
‫ﺑﺮﻧﺎﻣﻪ ﺧﻮﺩ ﺑﻪ ﺁﻧﻬﺎ ﻧﻴﺎﺯ ﺩﺍﺭﻳﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫﺪ ﭘﻴﺎﻡ ﻣﻨﺎﺳﺐ ﭼﺎﭖ ﺷﺪﻩ ﻭ ﺧﺮﻭﺟﻲ ‪ -1‬ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﺩﺭ ﻏﻴـﺮ‬
‫ﺍﻳﻦ ﺻﻮﺭﺕ ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪ .‬ﭘﺲ ﺍﺯ ﺍﺟﺮﺍﻱ ﺍﻳﻦ ﺗﺎﺑﻊ ﺍﻋﺪﺍﺩ ﺻﺤﻴﺤﻲ ﺑﺎ ﺷﻤﺎﺭﻩﻫﺎﻱ ‪ 0‬ﺗـﺎ ‪ nints-1‬ﺑـﺮﺍﻱ ﺷـﻤﺎ ﺗﻮﻟﻴـﺪ‬
‫ﻣﻲﺷﻮﺩ‪.‬‬
‫)‪void shi_set(int inum, int value‬‬
‫ﺍﺯ ﺍﻳﻦ ﺗﺎﺑﻊ ﺑﺮﺍﻱ ﺗﻨﻈﻴﻢ ﻣﻘﺪﺍﺭ ﻋﺪﺩ ﺻﺤﻴﺢ ﻣﺸﺘﺮﮎ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪ snum .‬ﺷﻤﺎﺭﻩ ﻋﺪﺩ ﺻﺤﻴﺤﻲ ﺍﺳﺖ ﮐﻪ ﻣﻲﺧﻮﺍﻫﻴـﺪ ﺑـﻪ ﺁﻥ‬
‫ﻣﻘﺪﺍﺭ ﺟﺪﻳﺪ ﺑﺪﻫﻴﺪ ﻭ ‪ value‬ﻣﻘﺪﺍﺭ ﻣﻮﺭﺩ ﻧﻈﺮ ﻣﻲﺑﺎﺷﺪ‪.‬‬
‫)‪int shi_get(int inum‬‬
‫ﺍﺯ ﺍﻳﻦ ﺗﺎﺑﻊ ﺑﺮﺍﻱ ﮔﺮﻓﺘﻦ ﻣﻘﺪﺍﺭ ﻋﺪﺩ ﺻﺤﻴﺢ ﻣﺸﺘﺮﮎ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪ snum .‬ﺷﻤﺎﺭﻩ ﻋﺪﺩ ﺻﺤﻴﺤﻲ ﺍﺳﺖ ﮐﻪ ﻣﻲﺧﻮﺍﻫﻴﺪ ﺑـﻪ ﺁﻥ‬
‫ﻣﻘﺪﺍﺭ ﺟﺪﻳﺪ ﺑﺪﻫﻴﺪ ﻭ ﺧﺮﻭﺟﻲ ﺗﺎﺑﻊ ﻣﻘﺪﺍﺭ ﻋﺪﺩ ﺻﺤﻴﺢ ﺍﺳﺖ‪.‬‬
‫)(‪int clean_integers‬‬
‫ﻓﻀﺎﻱ ﺍﺧﺘﺼﺎﺹ ﺩﺍﺩﻩ ﺷﺪﻩ ﺑﺮﺍﻱ ﺍﻋﺪﺍﺩ ﺻﺤﻴﺢ ﻣﺸﺘﺮﮎ ﺭﺍ ﺁﺯﺍﺩ ﻣﻲﮐﻨﺪ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻴﮑﻪ ﺧﻄﺎﻳﻲ ﺭﺥ ﺩﻫـﺪ ﭘﻴـﺎﻡ ﻣﻨﺎﺳـﺐ ﭼـﺎﭖ‬
‫ﺷﺪﻩ ﻭ ﺧﺮﻭﺟﻲ ‪ -1‬ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﺩﺭ ﻏﻴﺮ ﺍﻳﻦ ﺻﻮﺭﺕ ﺧﺮﻭﺟﻲ ﺻﻔﺮ ﺍﺳﺖ‪.‬‬
‫ﺷﺮﺡ ﭘﺮﻭﮊﻩ‬
‫ﻣﺴﺎﺋﻠﻲ ﮐﻪ ﺑﺎﻳﺪ ﺁﻧﻬﺎ ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﻨﻴﺪ ﻋﺒﺎﺭﺗﻨﺪ ﺍﺯ‪:‬‬
‫‪ .1‬ﻣﺴﺌﻠﻪ ﺧﻮﺍﻧﻨﺪﮔﺎﻥ ﻭ ﻧﻮﻳﺴﻨﺪﮔﺎﻥ )‪ (Readers-Writers‬ﺭﺍ ﺩﺭ ﺣﺎﻟﺘﻴﮑﻪ ﻣﺸﮑﻞ ﮔﺮﺳﻨﮕﻲ ﺑﺮﺍﻱ ﻫـﻴﭻ ﻧﻮﻳﺴـﻨﺪﻩ ﻭ‬
‫ﺧﻮﺍﻧﻨﺪﻩﺍﻱ ﺭﺥ ﻧﺪﻫﺪ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﻨﻴﺪ‪ .‬ﺗﻮﺟﻪ ﮐﻨﻴﺪ ﮐﻪ ﺩﺭ ﻫﺮ ﻟﺤﻈﻪ ﻳﺎ ﻳﮏ ﻧﻮﻳﺴﻨﺪﻩ ﺩﺭ ﺣﺎﻝ ﻧﻮﺷﺘﻦ ﺍﺳﺖ ﻭ ﻳـﺎ ‪n‬‬
‫ﺧﻮﺍﻧﻨﺪﻩ ﺩﺭ ﺣﺎﻝ ﺧﻮﺍﻧﺪﻥ ﮐﻪ ‪ n >= 0‬ﺍﺳﺖ‪ .‬ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﺍﺑﺘﺪﺍ ﭘﺎﺭﺍﻣﺘﺮﻫـﺎﻱ ﻭﺭﻭﺩﻱ ‪ r‬ﻭ ‪ w‬ﺭﺍ ﺍﺯ ﺧـﻂ ﻓﺮﻣـﺎﻥ‬
‫ﮔﺮﻓﺘﻪ ﻭ ﺳﭙﺲ ﺑﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺩﺳﺘﻮﺭ ‪ fork‬ﺗﻌﺪﺍﺩ ‪ r‬ﭘـﺮﺩﺍﺯﻩ ﺧﻮﺍﻧﻨـﺪﻩ ﺑـﺎ ﺷـﻤﺎﺭﻩ ﻫـﺎﻱ ‪ 1‬ﺗـﺎ ‪ r‬ﻭ ﺗﻌـﺪﺍﺩ ‪ w‬ﭘـﺮﺩﺍﺯﻩ‬
‫ﻧﻮﻳﺴﻨﺪﻩ ﺑﺎ ﺷﻤﺎﺭﻩ ﻫﺎﻱ ‪ 1‬ﺗﺎ ‪ w‬ﺗﻮﻟﻴﺪ ﮐﺮﺩﻩ ﻭ ﺳﭙﺲ ﺁﻧﻬﺎ ﺭﺍ ﺍﺟﺮﺍ ﮐﻨﺪ‪ .‬ﺍﺯ ﺳﻤﺎﻓﻮﺭﻫﺎ ﺑﺮﺍﻱ ﮐﻨﺘﺮﻝ ﻫﻤﺮﻭﻧﺪﻱ ﭘـﺮﺍﺯﻩ‪-‬‬
‫ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪.‬‬
‫ﻣﻮﺍﺭﺩ ﺯﻳﺮ ﺑﺎﻳﺪ ﺩﻗﻴﻘﺎ ﺩﺭ ﺧﺮﻭﺟﻲ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﭼﺎﭖ ﺷﻮﻧﺪ‪:‬‬
‫·‬
‫ﻫﺮﮔﺎﻩ ﺧﻮﺍﻧﻨﺪﻩ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ i‬ﺷﺮﻭﻉ ﺑﻪ ﺧﻮﺍﻧﺪﻥ ﮐﺮﺩ‪:‬‬
‫·‬
‫ﻫﺮﮔﺎﻩ ﺧﻮﺍﻧﺪﻥ ﺧﻮﺍﻧﻨﺪﻩ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ i‬ﺗﻤﺎﻡ ﺷﺪ‪:‬‬
‫·‬
‫ﻫﺮﮔﺎﻩ ﻧﻮﻳﺴﻨﺪﻩ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ i‬ﺷﺮﻭﻉ ﺑﻪ ﻧﻮﺷﺘﻦ ﮐﺮﺩ‪:‬‬
‫·‬
‫ﻫﺮﮔﺎﻩ ﻧﻮﺷﺘﻦ ﻧﻮﻳﺴﻨﺪﻩ ﺑﺎ ﺷﻤﺎﺭﻩ ‪ i‬ﺗﻤﺎﻡ ﺷﺪ‪:‬‬
‫‪R : i : Start‬‬
‫‪R : i : End‬‬
‫‪W : i : Start‬‬
‫‪W : i : End‬‬
‫·‬
‫·‬
‫·‬
‫·‬
‫ﺩﺭ ﺷﮑﻞ ﺯﻳﺮ ﻧﻤﻮﻧﻪﺍﻱ ﺍﺯ ﺧﺮﻭﺟﻲ ﺍﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﺩﺍﺩﻩ ﺷﺪﻩ ﺍﺳﺖ‪:‬‬
‫‪ .2‬ﻓﺮﺽ ﮐﻨﻴﺪ ﺗﻌﺪﺍﺩﻱ ﺩﺍﻧﺸﺠﻮ ﺩﺍﺭﻳﻢ ﮐﻪ ﻫﺮ ﻳﮏ ﻣﻲﺧﻮﺍﻫﺪ ﻳﮏ ﺳـﻮﺍﻝ ﺍﺯ ﺍﺳـﺘﺎﺩ ﺧـﻮﺩ ﺑﭙﺮﺳـﺪ‪ .‬ﺑـﺮﺍﻱ ﺍﻳـﻦ ﻣﻨﻈـﻮﺭ‬
‫ﺍﺗﻔﺎﻗﺎﺕ ﺯﻳﺮ ﺑﻪ ﺗﺮﺗﻴﺐ ﺭﻭﻱ ﻣﻴﺪﻫﻨﺪ‪:‬‬
‫·‬
‫ﺩﺍﻧﺸﺠﻮﻱ ‪ i‬ﻭﺍﺭﺩ ﺍﺗﺎﻕ ﺍﺳﺘﺎﺩ ﻣﻲ ﺷﻮﺩ‪.‬‬
‫·‬
‫ﺩﺍﻧﺸﺠﻮﻱ ‪ i‬ﺳﻮﺍﻝ ﺧﻮﺩ ﺭﺍ ﻣﻲﭘﺮﺳﺪ‪.‬‬
‫·‬
‫ﺍﺳﺘﺎﺩ ﺷﺮﻭﻉ ﺑﻪ ﺟﻮﺍﺏ ﺩﺍﺩﻥ ﻣﻴﮑﻨﺪ‪.‬‬
‫·‬
‫‪T : Answering to : i‬‬
‫ﺟﻮﺍﺏ ﺩﺍﺩﻥ ﺑﻴﻦ ‪ 0‬ﺗﺎ ‪ 2‬ﺛﺎﻧﻴﻪ ﻃﻮﻝ ﻣﻲﮐﺸﺪ!‬
‫‪S : i : Entered room‬‬
‫‪S : i : Asked question‬‬
‫·‬
‫ﺍﺳﺘﺎﺩ ﺟﻮﺍﺏ ﺩﺍﺩﻥ ﺭﺍ ﺗﻤﺎﻡ ﻣﻲﮐﻨﺪ‪.‬‬
‫‪T : Finished answering to : i‬‬
‫·‬
‫·‬
‫·‬
‫·‬
‫·‬
‫ﺩﺍﻧﺸﺠﻮﻱ ‪ i‬ﺗﺸﮑﺮ ﻣﻲﮐﻨﺪ‪.‬‬
‫·‬
‫ﺩﺍﻧﺸﺠﻮﻱ ‪ i‬ﺍﺯ ﺍﺗﺎﻕ ﺧﺎﺭﺝ ﻣﻲﺷﻮﺩ‪.‬‬
‫‪S : i : Thanks‬‬
‫‪S : i : Exited room‬‬
‫·‬
‫·‬
‫ﻣﺤﺪﻭﺩﻳﺘﻬﺎﻱ ﺯﻳﺮ ﺩﺭ ﺍﻳﻦ ﻣﺴﺌﻠﻪ ﻭﺟﻮﺩ ﺩﺍﺭﻧﺪ‪:‬‬
‫‪ .a‬ﺩﺭ ﻫﺮ ﻟﺤﻈﻪ ﺣﺪﺍﮐﺜﺮ ‪ 3‬ﺩﺍﻧﺸﺠﻮ ﻣﻲﺗﻮﺍﻧﻨﺪ ﺩﺭ ﺍﺗﺎﻕ ﺍﺳﺘﺎﺩ ﺑﺎﺷﻨﺪ‪.‬‬
‫‪ .b‬ﺍﺳﺘﺎﺩ ﺩﺭ ﻫﺮ ﻟﺤﻈﻪ ﺣﺪﺍﮐﺜﺮ ﺑﻪ ﻳﮏ ﺳﻮﺍﻝ ﭘﺎﺳﺦ ﻣﻲﺩﻫﺪ‪.‬‬
‫ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﺍﺑﺘﺪﺍ ﭘﺎﺭﺍﻣﺘﺮ ﻭﺭﻭﺩﻱ ‪ n‬ﺭﺍ ﺍﺯ ﺧﻂ ﻓﺮﻣـﺎﻥ ﮔﺮﻓﺘـﻪ ﻭ ﺳـﭙﺲ ﺑـﺎ ﺍﺳـﺘﻔﺎﺩﻩ ﺍﺯ ﺩﺳـﺘﻮﺭ ‪ fork‬ﺗﻌـﺪﺍﺩ ‪n‬‬
‫ﭘﺮﺩﺍﺯﻩ ﺩﺍﻧﺸﺠﻮ ﺑﺎ ﺷﻤﺎﺭﻩ ﻫﺎﻱ ‪ 1‬ﺗﺎ ‪ n‬ﺗﻮﻟﻴﺪ ﮐﺮﺩﻩ ﻭ ﺳﭙﺲ ﺁﻧﻬﺎ ﺭﺍ ﺍﺟﺮﺍ ﮐﻨﺪ‪ .‬ﺍﺯ ﺳﻤﺎﻓﻮﺭﻫﺎ ﺑﺮﺍﻱ ﮐﻨﺘـﺮﻝ ﻫﻤﺮﻭﻧـﺪﻱ‬
‫ﭘﺮﺩﺍﺯﻩﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪.‬‬
‫ﺩﺭ ﺷﮑﻞ ﺯﻳﺮ ﻧﻤﻮﻧﻪﺍﻱ ﺍﺯ ﺧﺮﻭﺟﻲ ﺍﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﺩﺍﺩﻩ ﺷﺪﻩ ﺍﺳﺖ‪:‬‬
‫‪ .3‬ﻓﺮﺽ ﮐﻨﻴﺪ ﺍﺯ ﺷﻤﺎ ﺧﻮﺍﺳﺘﻪ ﺷﺪﻩ ﺍﺳﺖ ﮐﻪ ﺑﺮﻧﺎﻣﻪﺍﻱ ﺑﺮﺍﻱ ﮐﻨﺘﺮﻝ ﻳﮏ ﺁﺳﺎﻧﺴﻮﺭ ﺑﻨﻮﻳﺴﻴﺪ‪ .‬ﺍﻳﻦ ﺁﺳﺎﻧﺴﻮﺭ ﺑﻴﻦ ﻃﺒﻘﺎﺕ‬
‫‪ 1‬ﺗﺎ ‪ 4‬ﺍﺯ ﺳﺎﺧﺘﻤﺎﻧﻲ ﺣﺮﮐﺖ ﻣﻲﮐﻨﺪ ﻭ ﺩﺭ ﺍﺑﺘﺪﺍ ﺩﺭ ﻃﺒﻘـﻪ ﺍﻭﻝ ﻗـﺮﺍﺭ ﺩﺍﺭﺩ‪ .‬ﺗـﺎ ﺯﻣﺎﻧﻴﮑـﻪ ﺩﺭﺧﻮﺍﺳـﺘﻲ ﻧﺮﺳـﻴﺪﻩ ﺑﺎﺷـﺪ‬
‫ﺁﺳﺎﻧﺴﻮﺭ ﺑﻲﺣﺮﮐﺖ ﺍﺳﺖ‪ .‬ﻫﻨﮕﺎﻣﻴﮑﻪ ﺁﺳﺎﻧﺴﻮﺭ ﺩﺭﺧﻮﺍﺳﺘﻲ ﺩﺭﻳﺎﻓﺖ ﮐﻨﺪ ﺷﺮﻭﻉ ﺑﻪ ﺣﺮﮐﺖ ﻣﻴﮑﻨـﺪ‪ .‬ﻧﺤـﻮﻩ ﺣﺮﮐـﺖ‬
‫ﺑﻪ ﺍﻳﻦ ﺗﺮﺗﻴﺐ ﺍﺳﺖ ﮐﻪ ﺁﺳﺎﻧﺴﻮﺭ ﺷﺮﻭﻉ ﺑﻪ ﺑﺎﻻ ﺭﻓﺘﻦ ﻣﻴﮑﻨﺪ ﻭ ﺩﺭ ﺣﻴﻦ ﺣﺮﮐﺖ ﺑﻪ ﺩﺭﺧﻮﺍﺳﺘﻬﺎ ﻋﻤﻞ ﻣﻲﮐﻨﺪ‪ .‬ﻫﺮﮔﺎﻩ‬
‫ﺁﺳﺎﻧﺴﻮﺭ ﺑﻪ ﻃﺒﻘﻪ ﭼﻬﺎﺭﻡ ﺑﺮﺳﺪ ﻭ ﻫﻨﻮﺯ ﺩﺭﺧﻮﺍﺳﺘﻲ ﻭﺟﻮﺩ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﺟﻬﺖ ﺣﺮﮐﺖ ﺑـﺮﻋﮑﺲ ﺷـﺪﻩ ﻭ ﺣﺮﮐـﺖ‬
‫ﺍﺩﺍﻣﻪ ﻣﻲﻳﺎﺑﺪ‪ .‬ﺑﻪ ﺍﻳﻦ ﺗﺮﺗﻴﺐ ﻣﺎﺩﺍﻣﻴﮑﻪ ﺩﺭﺧﻮﺍﺳﺘﻲ ﻭﺟﻮﺩ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ ﺁﺳﺎﻧﺴﻮﺭ ﺍﺯ ﻃﺒﻘﻪ ‪ 1‬ﺑﻪ ‪ 4‬ﺭﻓﺘﻪ ﻭ ﺳـﭙﺲ ﺍﺯ ‪4‬‬
‫ﺑﻪ ‪ 1‬ﺑﺮ ﻣﻲﮔﺮﺩﺩ ﻭ ﺍﻳﻦ ﺣﻠﻘﻪ ﺍﺩﺍﻣﻪ ﻣﻲﻳﺎﺑﺪ‪ .‬ﺩﺭ ﺿﻤﻦ ﻇﺮﻓﻴﺖ ﺁﺳﺎﻧﺴﻮﺭ ﻧﺎﻣﺤﺪﻭﺩ ﺍﺳﺖ ﻭ ﻫﺮ ﺗﻌﺪﺍﺩ ﺷـﺨﺺ ﻣـﻲ‪-‬‬
‫ﺗﻮﺍﻧﻨﺪ ﻫﻤﺰﻣﺎﻥ ﺳﻮﺍﺭ ﺁﻥ ﺑﺸﻮﻧﺪ‪ .‬ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﺜﺎﻝ ﻓﺮﺽ ﮐﻨﻴﺪ ﺁﺳﺎﻧﺴﻮﺭ ﺩﺭ ﻃﺒﻘﻪ ‪ 3‬ﺑﺎﺷﺪ ﻭ ﺷﺨﺼﻲ ﺩﺭﺧﻮﺍﺳﺖ ﺧﻮﺩ‬
‫ﺑﺮﺍﻱ ﺭﻓﺘﻦ ﺍﺯ ﻃﺒﻘﻪ ‪ 2‬ﺑﻪ ‪ 4‬ﺭﺍ ﺑﻪ ﺁﺳﺎﻧﺴﻮﺭ ﺑﺪﻫﺪ‪ .‬ﺩﺭ ﺍﻳﻦ ﺻﻮﺭﺕ ﺁﺳﺎﻧﺴﻮﺭ ﺑﻪ ﺗﺮﺗﻴﺐ ﺑﻪ ﺍﻳﻦ ﻃﺒﻘﺎﺕ ﻣـﻲﺭﻭﺩ ‪ 4 :‬ﻭ‬
‫‪ 3‬ﻭ ‪) 2‬ﺷﺨﺺ ﺳﻮﺍﺭ ﻣﻴﺸﻮﺩ( ﻭ ‪ 1‬ﻭ ‪ 2‬ﻭ ‪ 3‬ﻭ ‪) 4‬ﺷﺨﺺ ﭘﻴﺎﺩﻩ ﻣﻲﺷﻮﺩ(‪ .‬ﮔﺮﭼﻪ ﺍﻳﻦ ﻧﻮﻉ ﺣﺮﮐـﺖ ﺑﻬﻴﻨـﻪ ﻧﻴﺴـﺖ‬
‫ﻭﻟﻲ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺁﻥ ﺁﺳﺎﻧﺘﺮ ﺍﺳﺖ‪.‬‬
‫ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﺍﺑﺘﺪﺍ ﭘﺎﺭﺍﻣﺘﺮ ﻭﺭﻭﺩﻱ ‪ n‬ﺭﺍ ﺍﺯ ﺧﻂ ﻓﺮﻣـﺎﻥ ﮔﺮﻓﺘـﻪ ﻭ ﺳـﭙﺲ ﺑـﺎ ﺍﺳـﺘﻔﺎﺩﻩ ﺍﺯ ﺩﺳـﺘﻮﺭ ‪ fork‬ﺗﻌـﺪﺍﺩ ‪n‬‬
‫ﭘﺮﺩﺍﺯﻩ ‪ Person‬ﺑﺎ ﺷﻤﺎﺭﻩ ﻫﺎﻱ ‪ 1‬ﺗﺎ ‪ n‬ﺗﻮﻟﻴﺪ ﮐﺮﺩﻩ ﻭ ﻃﺒﻘﺎﺕ ﻣﺒﺪﺍ ﻭ ﻣﻘﺼﺪ ﻫﺮ ﺷﺨﺺ ﺭﺍ ﺑﺎ ﺗﻮﻟﻴﺪ ﺍﻋﺪﺍﺩ ﻣﺘﻔـﺎﻭﺕ‬
‫ﺗﺼﺎﺩﻓﻲ ﺑﻴﻦ ‪ 1‬ﺗﺎ ‪ 4‬ﻣﺸﺨﺺ ﮐﺮﺩﻩ ﻭ ﺳﭙﺲ ﺁﻧﻬﺎ ﺭﺍ ﺍﺟﺮﺍ ﮐﻨﺪ‪ .‬ﺍﺯ ﺳـﻤﺎﻓﻮﺭﻫﺎ ﺑـﺮﺍﻱ ﮐﻨﺘـﺮﻝ ﻫﻤﺮﻭﻧـﺪﻱ ﭘـﺮﺩﺍﺯﻩﻫـﺎ‬
‫ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪.‬‬
‫ﻣﻮﺍﺭﺩ ﺯﻳﺮ ﺑﺎﻳﺪ ﺩﻗﻴﻘﺎ ﺩﺭ ﺧﺮﻭﺟﻲ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﭼﺎﭖ ﺷﻮﻧﺪ‪:‬‬
‫·‬
‫ﺷﺨﺺ ‪ i‬ﺩﺭ ﻃﺒﻘﻪ ‪ f‬ﻗﺮﺍﺭ ﺩﺍﺭﺩ ﻭ ﻣﻲﺧﻮﺍﻫﺪ ﺑﻪ ﺻﺒﻘﻪ ‪ t‬ﺑﺮﻭﺩ‪:‬‬
‫‪P : i : Wants to go from f to t‬‬
‫·‬
‫ﺷﺨﺺ ‪ i‬ﻭﺍﺭﺩ ﺁﺳﺎﻧﺴﻮﺭ ﺷﺪ‪:‬‬
‫·‬
‫ﺷﺨﺺ ‪ i‬ﺍﺯ ﺁﺳﺎﻧﺴﻮﺭ ﺧﺎﺭﺝ ﺷﺪ‪:‬‬
‫·‬
‫ﺁﺳﺎﻧﺴﻮﺭ ﻭﺍﺭﺩ ﻃﺒﻘﻪ ‪ n‬ﺷﺪ‪:‬‬
‫‪P : i : Entered elevator‬‬
‫‪P : i : Exited elevator‬‬
‫‪Elevator entered floor n‬‬
‫ﺩﺭ ﺷﮑﻞ ﺯﻳﺮ ﻧﻤﻮﻧﻪﺍﻱ ﺍﺯ ﺧﺮﻭﺟﻲ ﺍﻳﻦ ﺑﺮﻧﺎﻣﻪ ﻧﻤﺎﻳﺶ ﺩﺍﺩﻩ ﺷﺪﻩ ﺍﺳﺖ‪:‬‬
‫·‬
‫·‬
‫·‬
‫·‬
‫ﺑﺮﺍﻱ ﺍﻧﺠﺎﻡ ﺍﻳﻦ ﭘﺮﻭﮊﻩ ﻣﺠﻤﻮﻋﻪ ﻓﺎﻳﻠﻬﺎﻱ ﺯﻳﺮ ﺩﺭ ﻗﺎﻟﺐ ﻓﺎﻳﻞ ‪ Prj2.tar.gz‬ﺩﺭ ﺍﺧﺘﻴﺎﺭ ﺷﻤﺎ ﻗﺮﺍﺭ ﮔﺮﻓﺘﻪﺍﻧﺪ‪:‬‬
‫)‪· Sem.h , Sem.c (Semaphore API‬‬
‫)‪· SHI.h , SHI.c (Shared Integers API‬‬
‫‪· RandSleep.h , RandSleep.c‬‬
‫ﺩﺭ ﺍﻳﻦ ﺩﻭ ﻓﺎﻳﻞ ﺗﺎﺑﻊ )‪ randSleep(int maxsec‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺷﺪﻩ ﺍﺳﺖ ﮐﻪ ﺍﻳﻦ ﺗﺎﺑﻊ ﺑﻴﻦ ‪ 0‬ﺗﺎ ‪ maxsec‬ﺛﺎﻧﻴﻪ ﺗﻮﻗـﻒ ﺩﺭ‬
‫ﺍﺟﺮﺍﻱ ﺑﺮﻧﺎﻣﻪ ﺷﻤﺎ ﺍﻳﺠﺎﺩ ﻣﻲﮐﻨﺪ )ﺑﺎ ﺩﻗﺖ ﻧﺎﻧﻮﺛﺎﻧﻴﻪ(‪ .‬ﺍﺯ ﺍﻳﻦ ﺗﺎﺑﻊ ﻣﻲﺗﻮﺍﻧﻴﺪ ﺑﺮﺍﻱ ﺩﺍﺷﺘﻦ ﺧﺮﻭﺟﻴﻬﺎﻱ ﺗﺼﺎﺩﻓﻲﺗﺮ ﺩﺭ ﺑﺮﻧﺎﻣﻪﻫـﺎﻱ‬
‫ﺧﻮﺩ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪.‬‬
‫‪· Sample.c‬‬
‫ﺩﺭ ﺍﻳﻦ ﻓﺎﻳﻞ ﺑﺮﺍﻱ ﺁﺷﻨﺎﻳﻲ ﺑﻴﺸﺘﺮ ﺷﻤﺎ ﺑﺎ ‪ API‬ﻫﺎﻱ ﺗﻮﻟﻴﺪ ﺷﺪﻩ‪ ،‬ﻣﺴﺌﻠﻪ ﺗﻮﻟﻴﺪﮐﻨﻨﺪﻩ – ﻣﺼﺮﻑ ﮐﻨﻨـﺪﻩ ﺑـﺎ ﺑـﺎﻓﺮ ﻧﺎﻣﺤـﺪﻭﺩ ﭘﻴـﺎﺩﻩ‬
‫ﺳﺎﺯﻱ ﺷﺪﻩ ﺍﺳﺖ‪.‬‬
‫‪RW.c‬‬
‫ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﺴﺌﻠﻪ ﺍﻭﻝ ﺭﺍ ﺩﺭ ﻗﺎﻟﺐ ﺍﻳﻦ ﻓﺎﻳﻞ ﺑﺎﻳﺪ ﺍﻧﺠﺎﻡ ﺩﻫﻴﺪ‪.‬‬
‫‪Questions.c‬‬
‫ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﺴﺌﻠﻪ ﺩﻭﻡ ﺭﺍ ﺩﺭ ﻗﺎﻟﺐ ﺍﻳﻦ ﻓﺎﻳﻞ ﺑﺎﻳﺪ ﺍﻧﺠﺎﻡ ﺩﻫﻴﺪ‪.‬‬
‫‪Elevator.c‬‬
‫ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﺴﺌﻠﻪ ﺳﻮﻡ ﺭﺍ ﺩﺭ ﻗﺎﻟﺐ ﺍﻳﻦ ﻓﺎﻳﻞ ﺑﺎﻳﺪ ﺍﻧﺠﺎﻡ ﺩﻫﻴﺪ‪.‬‬
‫‪Makefile‬‬
‫·‬
‫·‬
‫·‬
‫·‬
‫ﺍﺯ ﺍﻳﻦ ‪ Makefile‬ﻣﻲﺗﻮﺍﻧﻴﺪ ﺑﺮﺍﻱ ﺗﻮﻟﻴﺪ ﻓﺎﻳﻠﻬﺎﻱ ﺍﺟﺮﺍﻳﻲ ﺑﺮﻧﺎﻣﻪﻫﺎﻱ ﺧﻮﺩ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪.‬‬
‫ﻣﻼﺣﻈﺎﺕ‪:‬‬
‫‪ .1‬ﭘﺮﻭﮊﻩ ﺭﺍ ﺩﺭ ﮔﺮﻭﻫﻬﺎﻱ ﺩﻭ ﻧﻔﺮﻩ ﺍﻧﺠﺎﻡ ﺩﻫﻴﺪ‪.‬‬
‫‪ .2‬ﺑﻪ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻳﻬﺎﻱ ﻣﺸﺎﺑﻪ ﻧﻤﺮﻩ ﻣﻨﻔﻲ ﺗﻌﻠﻖ ﺧﻮﺍﻫﺪ ﮔﺮﻓﺖ‪.‬‬
‫ﺗﺤﻮﻳﻞ ﭘﺮﻭﮊﻩ‪:‬‬
‫ﺗﺤﻮﻳﻞ ﭘﺮﻭﮊﻩ ﺩﺭ ﺩﻭ ﻣﺮﺣﻠﻪ ﺻﻮﺭﺕ ﺧﻮﺍﻫﺪ ﮔﺮﻓﺖ‪ :‬ﺩﺭ ﻣﺮﺣﻠﻪ ﺍﻭﻝ ﺑﺎﻳﺪ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺧﻮﺩ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﻓﺎﻳـﻞ ﻓﺸـﺮﺩﻩ ﺷـﺪﻩ‬
‫)ﺑﺎ ﻧـﺎﻡ ‪ (StudentNumber1-StudentName1-StudentNumber2-StudentName2.tar.gz‬ﺣـﺪﺍﮐﺜﺮ ﺗـﺎ‬
‫ﺗﺎﺭﻳﺦ ‪ 84/10 /15‬ﺑﻪ ﺁﺩﺭﺱ ‪ ganji@ce.sharif.edu‬ﺍﺭﺳﺎﻝ ﮐﻨﻴﺪ )ﺑﻌـﺪ ﺍﺯ ﺍﻳـﻦ ﺗـﺎﺭﻳﺦ ﺑـﻪ ﺍﺯﺍﻱ ﻫـﺮ ﺭﻭﺯ ﺗـﺎﺧﻴﺮ ‪20‬‬
‫ﺩﺭﺻﺪ ﺍﺯ ﻧﻤﺮﻩ ﭘﺮﻭﮊﻩ ﺭﺍ ﺍﺯ ﺩﺳﺖ ﺧﻮﺍﻫﻴﺪ ﺩﺍﺩ(‪ .‬ﺯﻣﺎﻥ ﺗﺤﻮﻳﻞ ﺣﻀﻮﺭﻱ ﭘﺮﻭﮊﻩ ﻣﺘﻌﺎﻗﺒﺎﹰ ﺍﻋﻼﻡ ﺧﻮﺍﻫﺪ ﺷﺪ‪.‬‬
‫ﺩﺭ ﺻﻮﺭﺕ ﻧﻴﺎﺯ ﺑﻪ ﺍﻃﻼﻋﺎﺕ ﺑﻴﺸﺘﺮ ﻣﻲﺗﻮﺍﻧﻴﺪ ﺑﺎ ‪ ganji@ce.sharif.edu‬ﻳﺎ ‪ falaki@ce.sharif.edu‬ﺗﻤﺎﺱ ﺑﮕﻴﺮﻳﺪ‪.‬‬