Sunday, October 14, 2012

പ്രോഗ്രാം, പ്രോസസ്സ് - 6

യൂണിക്സ്/ലിനക്സ് സിസ്റ്റങ്ങളില്‍ ബൂട്ടിങ്ങിന് ശേഷം കെര്‍ണല്‍ തന്നെ നിര്‍മിക്കുന്ന പ്രോസസ്സാണ് ഇനിറ്റ്. ഇനിറ്റ് വരെ സിസ്റ്റം കെര്‍ണല്‍ മോഡിലായിരിക്കും. ഇനിറ്റ് പ്രവര്‍ത്തനമാരംഭിക്കുന്നതോടെ സിസ്റ്റം യൂസര്‍മോഡിലേക്ക് മാറുന്നു. ഇനിറ്റിന്റെ വകഭേദങ്ങളും  പ്രവര്‍ത്തനവും ഒരു പോസ്റ്റി വിശദീകരിക്കാം. ഇനിറ്റിനു ശേഷമുള്ള  എല്ലാ പ്രോസസ്സുകളും ഫോര്‍ക്ക് സിസ്റ്റം കോള്‍ ഉപയോഗിച്ച് സൃഷ്ടിക്കപ്പെടുന്നവയാണ്. ഇനിറ്റ് പ്രോസസ്സ് ഷെല്ലുകളോ ഗ്രാഫിക്കല്‍ യൂസര്‍ ഇന്റര്‍ഫേസുകളോ എക്സിക്യൂട്ട് ചെയ്യുന്നു. അപ്പോള്‍ ഉപഭോക്താവിന് കമ്പ്യൂട്ടര്‍ പ്രവര്‍ത്തിപ്പിക്കാനുള്ള ഉപാധികള്‍ ലഭ്യമാകും. ഉപഭോക്താവ് കമാന്റുകളോ മൗസോ ഉപയോഗിച്ച് ഒരു പുതിയ പ്രോഗ്രാം തുറക്കുമ്പോള്‍ സംഭവിക്കുന്ന കാര്യങ്ങള്‍ എന്തൊക്കഎയാണെന്ന് നോക്കാം. ഷെല്ലോ ഗ്രാഫിക്കല്‍ ഇന്റര്‍ഫേസോ ആദ്യം ഫോര്‍ക്ക് സിസ്റ്റം കോള്‍ ഉപയോഗിച്ച് അതിന്റെ തന്നെ ഒരു കോപ്പി നിര്‍മ്മിക്കുന്നു. ഈ കോപ്പി നിര്‍മ്മിക്കപ്പെടുന്ന വഴി ഇങ്ങനെയാണ്.
1. ഫോര്‍ക്ക് സിസ്റ്റം കോള്‍ ഉപയോഗിക്കപ്പെടുമ്പോള്‍ സിസ്റ്റം യൂസര്‍ മോഡില്‍ നിന്ന് കെര്‍ണല്‍ മോഡിലേക്ക് മാറുന്നു.
2. കെര്‍ണലിന്റെ സിസ്റ്റം കോള്‍ ഇന്റര്‍ഫേസ് ഫോര്‍ക്ക് സിസ്റ്റം കോളിലെ നിര്‍ദ്ദേശങ്ങള്‍ പ്രവര്‍ത്തിപ്പിക്കാന്‍ ആരംഭിക്കുന്നു.
3. സിസ്റ്റത്തില്‍  ഓരോ ഉപയോക്താവിനും ഒരു സമയത്ത് പ്രവര്‍ത്തിപ്പിക്കാനാകുന്ന പ്രോസസ്സുകളുടെ എണ്ണം തീരുമാനിക്കപ്പെട്ടിട്ടുണ്ടെങ്കില്‍ ആ പരിധി പാലിക്കപ്പെട്ടിട്ടുണ്ടോ എന്ന് പരിശോധിക്കപ്പെടുന്നു.
4. ഒരു പ്രോസസ്സ് ആരംഭിക്കാനാവശ്യമായ വിഭവങ്ങള്‍ സിസ്റ്റത്തില്‍ ബാക്കിയുണ്ടോ എന്ന് പരിശോധിക്കപ്പെടുന്നു (മെമ്മറി ഇതില്‍ പ്രധാനമാണ്)
5. പുതിയ ഒരു എന്‍ട്രി പ്രോസസ്സ് ടേബിളില്‍ സൃഷ്ടിക്കപ്പെടുന്നു. യു-ഏരിയക്കായി മെമ്മറി തയ്യാറാക്കുന്നു.
6. ഫോര്‍ക്ക് ഉപയോഗിച്ച പ്രോസസ്സിന്റെ ടെക്സ്റ്റ്, ഡാറ്റ, സ്റ്റാക്ക്, ഹീപ്പ് എന്നിവയുടെ കോപ്പി തയ്യാറാക്കപ്പെടുന്നു. ഇവിടെ ശരിക്കും കോപ്പി ഉണ്ടാക്കുകയില്ല. ടെക്സ്റ്റ് സെഗ്മന്റ് ആദ്യത്തെ പ്രോസസ്സിന്റെ തന്നെ ഉപയോഗിക്കപ്പെടും. ശരിക്കും കോപ്പികള്‍ ഉണ്ട് എന്ന് തോന്നിപ്പിക്കുകയും  അവിടെ പഴയ സെഗ്മെന്റുകളുടെ വിലാസം രേഖപ്പെടുത്തുകയും ആണ് ചെയ്യുന്നത്. സ്റ്റാക്ക്, ഡാറ്റ, ഹീപ്പ് സെഗ്മന്റുകള്‍ ടെക്സ്റ്റ് സെഗ്മന്റില്‍ നിന്നും വ്യത്യസ്തമായി മാറ്റങ്ങള്‍ വരുത്താന്‍ അനുവദിക്കപ്പെട്ടവയായതിനാല്‍ അവിടെ കോപ്പി ഓണ് റൈറ്റ് എന്ന സങ്കേതം ഉപയോഗിക്കും. അതായത് അവയില്‍ മാറ്റങ്ങള്‍ വരുത്തപ്പെടുന്നത് വരെ ആദ്യമുണ്ടായിരുന്നവ തന്നെ ഉപയോഗിക്കുകയും മാറ്റങ്ങള്‍ വരുത്തപ്പെട്ട ശേഷം മാത്രം പുതിയ പതിപ്പ് സൃഷ്ടിക്കുകയും ചെയ്യുന്നു.

ഇപ്പോള്‍ സിസ്റ്റത്തില്‍ ഒരേ പ്രോസസ്സിന്റെ രണ്ട് കോപ്പി ഉണ്ടായി. ഫലത്തില്‍ ഫോര്‍ക്ക് സിസ്റ്റം കോള്‍ ഉപയോഗിച്ച രണ്ട് പ്രോസസ്സുകള്‍. ഫോര്‍ക്ക് സിസ്റ്റം കോളിന് രണ്ട് വ്യത്യസ്ത റിട്ടേണ്‍ മൂല്യങ്ങള്‍ ഉണ്ട്. സാധാരണ ഫങ്ങ്ഷനുകള്‍ അവയെ വിളിച്ച ഒരു പ്രോസസ്സിലേക്ക് മാത്രമേ മൂല്യങ്ങള്‍ തിരികെ നല്‍കുകയുള്ളു. എന്നാല്‍ ഫോര്‍ക്ക് പേരന്റ് പ്രോസസ്സിലേക്കും ചൈല്‍ഡ് പ്രോസസ്സിലേക്കും ഓരോ മൂല്യങ്ങള്‍ മടക്കി നല്‍കും. വിജയകരമായ ഫോര്‍ക്ക് പേരന്റ് പ്രോസസ്സിലേക്ക് ചൈല്‍ഡ് പ്രോസസ്സിന്റെ പിഐഡിയും ചൈല്‍ഡ് പ്രോസസ്സിലേക്ക് പൂജ്യവും മടക്കി നല്‍കുന്നു. ഇത് ഉപയോഗിച്ചാണ് ഇപ്പോള്‍ പ്രവര്‍ത്തിക്കുന്നത് പേരന്റാണോ ചൈല്‍ഡ് ആണോ എന്ന് മനസ്സിലാക്കാന്‍ സാധിക്കുന്നത്. സി പ്രോഗ്രാമിങ്ങ് വശമുള്ളവര്‍ക്ക് ഈ ഉദാഹരണം പരീക്ഷിക്കാവുന്നതാണ്.

 #include <stdio.h>  
 #include <stdlib.h>  
 #include <unistd.h>  
   
 int main(void)  
 {  
     int pid;  
   
     pid = fork();  
     if (pid == -1) {  
         printf("fork failed..\n");  
         exit(-1);  
     }  
   
     if (pid == 0) {  
         printf("I am the child process. My PID is %d\n", getpid());  
         exit(0);  
     } else {  
         printf("I am the parent process PID is %d. Child PID is %d\n",getpid(), pid);  
     }  
   
     return 0;  
 }  

ഇതിനെ fork.c എന്ന ഫയലില്‍ സേവ് ചെയ്യുക. അതിനു ശേഷം ടെര്‍മിനലില്‍
gcc fork.c -o fork എന്ന് ടൈപ്പ് ചെയ്ത് എന്റര്‍ അമര്‍ത്തുക. പ്രവര്‍ത്തിപ്പിക്കാന്‍ ./fork എന്ന് ടൈപ്പ് ചെയ്ത് എന്റര്‍ അമര്‍ത്തുക. താഴെക്കാണുന്നതിന് സമാനമായ ഔട്ട്പുട്ട് ലഭിക്കും,
I am the parent process PID is 3691. Child PID is 3692
I am the child process. My PID is 3692
if സ്റ്റേറ്റ്മെന്റ് ഉപയോഗിക്കുമ്പോള്‍ സാധാരണയായി നിര്‍ദ്ദേശത്തിലെ ഒരു ഭാഗം മാത്രം പ്രവര്‍ത്തിക്കുന്നിടത്ത് ഇവിടെ രണ്ട് ഭാഗങ്ങളും പ്രവര്‍ത്തിക്കുന്നതായി കാണാം. ശരിക്കും  ഇത് രണ്ട് വ്യത്യസ്ത പ്രോസസ്സുകളില്‍ നിന്നാണ് വരുന്നത്. ആദ്യം ചൈല്‍ഡ്‌ പ്രവര്‍ത്തിക്കുമോ പേരന്റ് പ്രവര്‍ത്തിക്കുമോ എന്ന് പറയാന്‍ സാധിക്കുകയില്ല. സിസ്റ്റം കോള്‍ പൂര്‍ത്തിയായ ശേഷം പ്രോസസ്സ് വീണ്ടും യൂസര്‍ മോഡിലേക്ക് തന്നെ മടങ്ങി വരുന്നു.

ഒരു പുതിയ പ്രോസസ്സ് ഇവിടെ സൃഷ്ടിക്കപ്പെട്ടെങ്കിലും അത് ആദ്യത്തെ പ്രോസസ്സിന്റെ തന്നെ പകര്‍പ്പാണെന്ന് മനസ്സിലാക്കിയിരിക്കുമല്ലോ. എന്നാല്‍ നമുക്കാവശ്യം ഒരു പുതിയ പ്രോഗ്രാമിനെ പ്രവര്‍ത്തിപ്പിക്കലാണ്. ഇതിനായി ഉപയോഗിക്കുന്ന സിസ്റ്റം കോള്‍ ആണ് എക്സക്ക് (exec). ഈ സിസ്റ്റം കോള്‍ ചെയ്യുന്നത് അതിനെ ഉപയോഗിച്ച പ്രോസസ്സിന്റെ സെഗ്മന്റുകള്‍ മാറ്റി അവിടെ ഒരു പുതിയ പ്രോഗ്രാമില്‍ നിന്നുള്ള സെഗ്‌‌മന്റുകള്‍ ചേര്‍ക്കുകയാണ്. ഇതുവഴി ഒറിജിനല്‍ പ്രോസസ്സ് ഇല്ലാതാകുകയും പകരം പുതിയ പ്രോഗ്രാം പ്രോസസ്സായി അവിടെ വരികയും ചെയ്യുന്നു. ഇതിന്റെ പ്രവര്‍ത്തനം താഴെപ്പറയുന്നത് പോലെയാണ്.
1. എക്സെക്ക് സിസ്റ്റം കോള്‍ ഉപയോഗിക്കുമ്പോള്‍ പ്രതിപാദിക്കപ്പെട്ട എക്സിക്യൂട്ടബിള്‍ ഫയല്‍ ഡിസ്കില്‍ കണ്ടെത്തുക. (ഫയല്‍ അനുബന്ധമായ ക്രിയകളുടെ വിശദാംശങ്ങള്‍ക്കായി ഫയല്‍ സിസ്റ്റങ്ങളെക്കുറിച്ചുള്ള പോസ്റ്റുകള്‍ കാണുക)
2. ആ ഫയല്‍ സാധുവായ ഒരു പ്രോഗ്രാം ആണോ എന്ന് പരിശോധിക്കുക (elf ഫയലുകളെപ്പറ്റി നേരത്തെ പ്രദിപാദിച്ചിരുന്നു)
3. സാധുവായ ഒരു പ്രോഗ്രാം ആണെങ്കില്‍ അതില്‍ നിന്ന് വിവിധ സെഗ്മന്റുകളെക്കുറിച്ചുള്ള വിവരങ്ങള്‍ വായിക്കുകയും അവയെ മെമ്മറിയിലേക്ക് കൊണ്ടുവരികയും ചെയ്യുക.
4. നിലവിലെ സെഗ്മന്റുകളെ നശിപ്പിക്കുകയും അവക്ക് പകരം പുതിയ സെഗ്മെന്റുകള്‍ അവിടെ ചേര്‍ക്കുകയും ചെയ്യുക.
5. പുതിയ പ്രോഗ്രാമിന്റെ തുടക്കം മുതല്‍ പ്രവര്‍ത്തനം ആരംഭിക്കുക.

ഇവിടെ ശ്രദ്ധിക്കേണ്ട ഒരു പ്രധാന കാര്യം വിജയകരമായ ഒരു എക്സെക്ക് സിസ്റ്റം കോള്‍ ഫോര്‍ക്ക് സിസ്റ്റം കോള്‍ ചെയ്തതുപോലെ മൂല്യങ്ങളൊന്നും മടക്കി നല്‍കുന്നില്ല. ഒരു ഫങ്ങ്ഷന്‍ റിട്ടേണ്‍ ചെയ്യുന്നത് അതിനെ വിളിച്ച പ്രോസസ്സിലേക്കാണ്. ഇവിടെ എക്സെക്കിനെ വിളിച്ച പ്രോസസ്സ് ബാക്കിയില്ല. അവിടെ പുതിയ പ്രോഗ്രാം പ്രവര്‍ത്തനം തുടങ്ങിയിരിക്കുന്നു. അതിനാല്‍ തന്നെ വിജയകരമായ എക്സെക്കില്‍ നിന്ന് റിട്ടേണ്‍ ഇല്ല. (ഇത് മിക്കവാറും ഇന്റര്‍വ്യൂകളില്‍ ഒക്കെ ചോദിക്കാറുള്ള ഒരു ചോദ്യമാണ്) മുകളിലെ പ്രോഗ്രാമിനെ അല്‍പം പരിഷ്കരിച്ച് ls എന്ന പ്രോഗ്രാമിനെ എങ്ങനെ പ്രവര്‍ത്തിപ്പിക്കം എന്ന് നോക്കാം. ഷെല്ലുകള്‍ എങ്ങനെ പ്രവര്‍ത്തിക്കുന്നു എന്ന് മനസ്സിലാക്കാന്‍ ഇത് ഉപകരിക്കും. സി പ്രോഗ്രാമിങ്ങില്‍ എക്സെക്ക് നേരിട്ട് ഉപയോഗിക്കാന്‍ വിഷമമാണ്. അതിനാല്‍ സി ലൈബ്രറി നല്‍കുന്ന execl, execlp, execle, execv, execvp, execvpe എന്ന വകഭേദങ്ങളില്‍ ഒന്ന് ഉപയോഗിക്കാം. ഇവയൊക്കെ ഉള്ളില്‍ എക്സെക്ക് തന്നെയാണ് ഉപയോഗിക്കുന്നത്.

 #include <stdio.h>  
 #include <stdlib.h>  
 #include <unistd.h>  
   
 int main(void)  
 {  
     int pid, ret;  
   
     pid = fork();  
     if (pid == -1) {  
         printf("fork failed..\n");  
         exit(-1);  
     }  
   
     if (pid == 0) {    
         printf("I am the child process. Now executing ls\n");  
         ret = execl("/bin/ls", "ls", "/", NULL);  
         if (ret == -1) {   
             printf("exec failed\n");  
         }   
     } else {  
         printf("I am the parent process PID is %d. Child PID is %d\n",getpid(), pid);  
     }  
   
     return 0;  
 }  

ആദ്യത്തെ പ്രോഗ്രാമിനെ മേലെ കാണുന്നതുപോലെ മാറ്റുക. ബാക്കി നിര്‍ദ്ദേശങ്ങള്‍ പഴയത് തന്നെ. ഇവിടെ താരതമ്യേന എളുപ്പമുള്ള execl എന്ന രൂപമാണ് ഉപയോഗിച്ചിരിക്കുന്നത്. അതിലെ ആദ്യത്തെ പരാമീറ്റര്‍ എക്സിക്യൂട്ട് ചെയ്യണ്ട പ്രോഗ്രാമിന്റെ പാത്ത് ആണ്. ബാക്കിയുള്ളവ ആ പ്രോഗ്രാമിന് ഉള്ള ആര്‍ഗ്യുമെന്റുകള്‍. യൂണിക്സ് സിസ്റ്റങ്ങളില്‍ ഒരു പ്രോഗ്രാമിന്റെ ആദ്യത്തെ ആര്‍ഗ്യുമെന്റായി ആ പ്രോഗ്രാമിന്റെ തന്നെ പേര് നല്‍കുന്നതാണ് കീഴ്‌‌വഴക്കം. വിവിധ പേരുകളില്‍ ഉപയോഗിക്കുമ്പോള്‍ വിവിധ തരത്തില്‍ പ്രവര്‍ത്തിക്കുന്ന പ്രോഗ്രാമുകള്‍ തയ്യാറാക്കാന്‍ ഇതുവഴി സാധിക്കും. അതാണ് രണ്ടാമത്തെ ആര്‍ഗ്യുമെന്റായി ls എന്ന് തന്നെ കൊടുത്തിരിക്കുന്നത്. മൂന്നാമതെ ആര്‍ഗ്യുമെന്റ്‌‌ "/" ആണ്. / എന്ന പാത്തിലെ ഫയലുകളുടെ പട്ടിക നല്‍കാന്‍ ls പ്രോഗ്രാമിനോട് ആവശ്യപ്പെടുന്നതിനാണ് ഇത്. അവസാനമായി NULL എന്നത് സെന്റിനല്‍ ആര്‍ഗ്യുമെന്റ് അഥവാ സെന്റിനല്‍ എന്നറിയപ്പെടുന്നു. വ്യത്യസ്ത എണ്ണത്തിലുള്ള പരാമീറ്ററുകള്‍ സ്വീകരിക്കുന്ന ഫങ്ങ്ഷനുകളോട് ഇതാണ് അവസാനത്തെ പരാമീറ്റര്‍ എന്ന് സൂചിപ്പിക്കാന്‍ ഇവ ഉപയോഗിക്കുന്നു. (NULL എന്നത് സെന്റിനല്‍ അല്ല. അതിന് മറ്റ് ഉപയോഗങ്ങള്‍ ഉണ്ട്. ഇനി പരാമീറ്ററുകള്‍ ഇല്ല എന്നത് സൂചിപ്പിക്കാനായി ഉപയോഗിക്കുന്നവയെ ആണ് സെന്റിനല്‍ എന്ന് വിളിക്കുന്നത്. എക്സെക്ക് പ്രതീക്ഷിക്കുന്ന സെന്റിനല്‍ NULL ആണ്). ls കമാന്റ് -l എന്ന ആര്‍ഗ്യുമെന്റ് സ്വീകരിക്കും. ls -l എന്നുപയോഗിക്കുമ്പോള്‍ ലഭിക്കുന്ന രീതിയിലുള്ള ഔട്ട്പുട്ട് ലഭിക്കാന്‍  ret = execl("/bin/ls", "ls", "-l", "/", NULL); എന്നാക്കി ആ വരിയെ മാറ്റിയാല്‍ മതി.

ഒരു പ്രോസസ്സിലെ തന്നെ സ്വതന്ത്രമായ ഒരു ഭാഗം മറ്റൊരു പ്രോസസ്സ് പോലെ ഷെഡ്യൂള്‍ ചെയ്യാന്‍ സാധിക്കുന്ന തരത്തില്‍ പ്രവര്‍ത്തിപ്പിക്കുക എന്നതാണ് ത്രെഡുകള്‍ വഴി ചെയ്യുന്നത്. ഒരു പ്രോസസ്സില്‍ ചിലപ്പോള്‍ ത്രെഡുകള്‍ ഉണ്ടാകാം. ഈ ത്രെഡുകള്‍ക്ക് വ്യത്യസ്ത സ്റ്റാക്ക് സെഗ്‌‌മന്റുകള്‍ ഉണ്ടായിരിക്കുമെങ്കിലും ടെക്സ്റ്റ്, ഡാറ്റ തുടങ്ങിയ സെഗ്മന്റുകള്‍ ഒക്കെ ഒന്നുതന്നെ ആയിരിക്കും. ലിനക്സില്‍ ഒരു ത്രെഡ് സൃഷ്ടിക്കാന്‍ ഉപയോഗിക്കുന്ന സിസ്റ്റം കോള്‍ ക്ലോണ്‍ (clone) ആണ്. ഇത് ഒരു പ്രോഗ്രാമില്‍ നേരിട്ട് ഉപയോഗിക്കുന്നതിന് പകരം  പി-ത്രെഡ്‌ പോലെ ത്രെഡുകള്‍ കൈകാര്യം ചെയ്യാനുള്ള ലൈബ്രറികള്‍ എന്തെങ്കിലും  ഉപയോഗിക്കുന്ന രീതിയാണ് ശുപാര്‍ശ ചെയ്യപ്പെട്ടിരിക്കുന്നത്.

പ്രോസസ്സ് ടേബിള്‍, യു-ഏരിയ എന്നിവയെക്കുറിച്ച് വിശദമായി അടുത്ത പോസ്റ്റില്‍.

18 comments:

  1. പോസ്റ്റിന്റെ തുടക്കം വായിച്ചപ്പോഴുള്ള സംശയം ആദ്യംതന്നെ പങ്കുവക്കുന്നു.

    //ഒരു പുതിയ പ്രോഗ്രാം തുറക്കുമ്പോള്‍ സംഭവിക്കുന്ന കാര്യങ്ങള്‍ എന്തൊക്കഎയാണെന്ന് നോക്കാം. ഷെല്ലോ ഗ്രാഫിക്കല്‍ ഇന്റര്‍ഫേസോ ആദ്യം ഫോര്‍ക്ക് സിസ്റ്റം കോള്‍ ഉപയോഗിച്ച് അതിന്റെ തന്നെ ഒരു കോപ്പി നിര്‍മ്മിക്കുന്നു.//

    മറ്റൊരു പ്രോഗ്രാമിനെ പ്രവർത്തിപ്പിക്കുന്നതിന് ഒരു പ്രോസസ് എന്തിനാണ് സ്വന്തം പകർപ്പുണ്ടാക്കുന്നത് എന്ന് സംശയം.

    (പോസ്റ്റ് മുഴുവൻ വായിച്ചില്ല. ആദ്യത്തെ പ്രോഗ്രാം എക്സിക്യൂട്ട് ചെയ്തിട്ട് സംശയങ്ങൾ ഇനിയും ചോദിക്കാം :))

    ReplyDelete
  2. ഒരു പുതിയ പ്രോസസ്സ് ഉണ്ടാക്കാനുള്ള ഒരേ ഒരു മാര്‍ഗ്ഗം ഫോ‌‌ര്‍ക്ക് ആണ്. ഫോര്‍ക്ക് ഒരു പ്രോസസ്സിന്റെ കോപ്പി ആണ് ഉണ്ടാക്കുക. ഇതിന് പല മെച്ചങ്ങളുമുണ്ട്. ഉദാഹരണത്തിന് തുറന്നിരിക്കുന്ന ഫയലുകളുടെ ഡിസ്ക്രിപ്റ്ററുകള്‍, നെറ്റ്‌‌വര്‍ക്ക് സോക്കറ്റുകള്‍ ഇതൊക്കെ ചൈല്‍ഡ് പ്രോസസ്സിനും ലഭ്യമാകുന്നു. ത്രെഡുകള്‍ ലഭ്യമല്ലാത്ത സാഹചര്യങ്ങളില്‍ പ്രോഗ്രാമിലെ ഒരു ഭാഗം സ്വതന്ത്രമായി പ്രവര്‍ത്തിപ്പിക്കാന്‍ ഈ വഴി ഉപയോഗിക്കാം. ഒരു നെറ്റ്‌‌വര്‍ക്ക് സെര്‍വര്‍ പ്രോഗ്രാം ആണെങ്കില്‍ ഓരോ ക്ലയന്റ് പ്രോസസ്സും കണക്റ്റ് ചെയ്യുമ്പോള്‍ അതിനെ കൈകാര്യം ചെയ്യാന്‍ ഒരു പ്രോസസ്സ് ഉണ്ടാക്കാം. അതിനെല്ലാം ഉള്ള കോഡ് ഒരൊറ്റ പ്രോഗ്രാമില്‍ തന്നെ എഴുതുകയും ചെയ്യാം. സങ്കീര്‍ണമായ പ്രോഗ്രാമുകളില്‍ ഇത് ആവശ്യമുണ്ടാകും. പിന്നെ ചൈല്‍ഡ് പ്രോസസ്സ് പ്രവര്‍ത്തനം അവസാനിപ്പിക്കുമ്പോള്‍ പേരന്റ് പ്രോസസ്സിന് അറീയാന്‍ സാധിക്കും. ഇക്കാര്യങ്ങള്‍ തുടര്‍ന്ന് വരുന്ന പോസ്റ്റുകളില്‍ ഉള്‍പ്പെടുത്തുന്നുണ്ട്. ചൈല്‍ഡിനും പേരന്റിനും പൊതുവായുള്ള കാര്യങ്ങളും എല്ലാം.ഇത് പോസിക്സ് സ്റ്റാന്‍ഡേര്‍ഡ് അനുസരിച്ചാണെന്ന് തോന്നുന്നു.

    ReplyDelete
    Replies
    1. ok. തുടർന്ന് എക്സെക്കിനെക്കുറിച്ച് വായിച്ചപ്പോൾ കൂടുതൽ മനസിലായി.

      മറ്റൊരു സംശയമുണ്ടായിരുന്നത്, ഫോർക്കുപയോഗിച്ചുണ്ടാക്കുന്ന പ്രോസസിലെ കോഡ് തുടക്കം മുതൽ പ്രവർത്തിക്കുമോ എന്നതായിരുന്നു. എന്നാൽ പ്രവർത്തിച്ചുകൊണ്ടിരിക്കുന്ന പ്രോസസിന്റെ തനിപ്പകർപ്പായതിനാൽ ഫോർക്ക് വിളിച്ചതിനു തൊട്ടു താഴെയുള്ള വരി മുതലേ ചൈൽഡ് പ്രോസസ് പ്രവർത്തിക്കൂ എന്നു മനസിലാക്കി. ശരിയല്ലേ?

      Delete
    2. അതെ. പ്രോഗ്രാമിന്റെ അല്ല, പ്രോസസ്സിന്റെ കോപ്പി ആണ് ഉണ്ടാക്കപ്പെടുന്നത്. അതില്‍ പ്രോസസ്സിന്റെ അപ്പോളത്തെ അവസ്ഥ ഉള്‍പ്പെട്ടിരിക്കും. അതായത് എവിടെവരെയായി എക്സിക്യൂഷന്‍, ഏതൊക്കെ ഫയലുകള്‍ ആ പ്രോസസ്സില്‍ തുറന്നിട്ടുണ്ട് എന്നിവയെല്ലാം. അതുകൊണ്ടാണ് ഫോര്‍ക്കിന് താഴത്തെ വരിയില്‍ നിന്നും പ്രവര്‍ത്തനം തുടരുന്നത്.

      Delete
  3. ഉദാഹരണമായി പ്രോഗ്രാമുകള്‍ നല്‍കുന്നത് പ്രോഗ്രാമിങ്ങില്‍ താല്‍പര്യമില്ലാത്തവര്‍ക്ക് വിഷമമുണ്ടാക്കാന്‍ സാധ്യതയുണ്ടോ? അത് ഒഴിവാക്കണോ? ചെറിയ ചെറിയ പ്രോഗ്രാമുകള്‍ നല്‍കുന്നത് താല്‍പര്യമുള്ളവര്‍ക്ക് സ്വയം പരീക്ഷണങ്ങള്‍ നടത്തി മനസ്സിലാക്കാനും ഒരു തിയറി ലെവലിലെ മടുപ്പ് ഒഴിവാക്കാനും സഹായകമാകും എന്ന് എനിക്ക് തോന്നി..

    ReplyDelete
    Replies
    1. ഉദാഹരണങ്ങൾ തീർച്ചയായും നല്ലതാണ്. ഈ ഉദാഹരണങ്ങളില്ലെങ്കിൽ ഈ പോസ്റ്റ് നിർജ്ജീവമായിരുന്നേനേ.

      Delete
  4. //ഇവിടെ എക്സെക്കിനെ വിളിച്ച പ്രോസസ്സ് ബാക്കിയില്ല. അവിടെ പുതിയ പ്രോഗ്രാം പ്രവര്‍ത്തനം തുടങ്ങിയിരിക്കുന്നു.//

    പ്രോസസ് ടെർമിനേറ്റായിട്ടില്ലല്ലോ. എക്സെക്കിനെ വിളിച്ച അതേ പ്രോസസ് തന്നെയാണ് പുതിയ പ്രോഗ്രാമിനെ പ്രവർത്തിപ്പിക്കുന്നത് എന്നെഴുതിയാൽ കൂടുതൽ നന്നായിരിക്കില്ലേ?

    ReplyDelete
    Replies
    1. ഒരു ഫങ്‌‌ഷന്‍ അതിനെ വിളിച്ച പ്രോസസ്സിലേക്ക് റിട്ടേണ്‍ ചെയ്യണമെങ്കില്‍ വിളിക്കുമ്പോള്‍ ഉണ്ടായിരുന്ന സ്റ്റാക്ക് ഫ്രെയിം അവിടെ വേണം. എക്സെക്കിന് ശേഷം അതിനെ വിളിച്ച പ്രോസസ്സുമായി ബധപ്പെട്ട സെഗ്‌‌മെന്റുകള്‍ ഒന്നും ബാക്കി കാണില്ല. പ്രോസസ്സ് ഒന്നുതന്നെ ആണ്. കെര്‍ണലിന്റെ ഭാഗത്ത് നിന്ന് നോക്കുകയാണെങ്കില്‍ മാത്രം.

      Delete
  5. //യൂണിക്സ് സിസ്റ്റങ്ങളില്‍ ഒരു പ്രോഗ്രാമിന്റെ ആദ്യത്തെ ആര്‍ഗ്യുമെന്റായി ആ പ്രോഗ്രാമിന്റെ തന്നെ പേര് നല്‍കുന്നതാണ് കീഴ്‌‌വഴക്കം.//

    ഇതൊരു കീഴ്വഴക്കമാണോ? നിബന്ധനതന്നെയല്ലേ?

    ReplyDelete
    Replies
    1. നിര്‍ബന്ധമൊന്നുമില്ല. മുകളിലത്തെ പ്രോഗ്രാമില്‍ തന്നെ പരീക്ഷിക്കാവുന്നതാണ്. പേര് പ്രതീക്ഷിക്കുന്ന പ്രോഗ്രാമുകള്‍ ആണെങ്കില്‍ മാത്രമെ പ്രശ്‌‌നമുണ്ടാവുകയുള്ളു.

      Delete
    2. മുകളിലെ പ്രോഗ്രാമിൽ പരീക്ഷിച്ചുനോക്കിയിരുന്നു. പേരിന്റെ ആർഗ്യുമെന്റ് ഒഴിവാക്കിയാൽ,വർക്കിങ് ഡയറക്റ്ററിയിലെ ഫയലുകൾ ലിസ്റ്റ് ചെയ്യും.

      കമാൻഡ്‌ലൈനിൽ നിന്ന് ഒരു പ്രോഗ്രാം എക്സിക്യൂട്ട് ചെയ്യുകയാണെങ്കിൽ പ്രോഗ്രാമിനകത്ത് ആർഗ്യുമെന്റുകളുടെ പട്ടിക നോക്കിയാൽ കമാൻഡ് തന്നെ ആദ്യത്തെ ആർഗ്യുമെന്റായി കിട്ടുന്ന അനുഭവം ഉണ്ട്. അതിനർത്ഥം എല്ലാ പ്രോഗ്രാമുകളും ആദ്യത്തെ ആർഗ്യുമെന്റ് അതിന്റെ പേരുതന്നെയായിരിക്കും എന്ന പൊതുതത്വം അംഗീകരിക്കേണ്ടതല്ലേ?

      Delete
    3. ok.. ഷെല്ലുകൾ ഇത്തരത്തിൽ (പേരൊടൊപ്പം) അവയെ ലോഡ് ചെയ്യുന്നതുകൊണ്ടാണല്ലോ അല്ലേ അത്. ഇപ്പൊപ്പിടികിട്ടി.

      Delete
    4. ആദ്യത്തെ ആര്‍ഗ്യു‌‌മെന്റ് ഒഴിവാക്കുകയല്ല, അവിടെ മറ്റെന്തെങ്കിലും പേര് കൊടുക്കുകയാണ് വേണ്ടത്. ആദ്യത്തെ ആര്‍ഗ്യുമെന്റ് പ്രോഗ്രാമും പരിഗണിക്കുകയില്ല. പ്രോഗ്രാമിന്റെ പേര് പരിശോധിക്കുന്നില്ലെങ്കില്‍. അതുകൊണ്ട്‌ അത് ഒഴിവാക്കിയപ്പോള്‍ ലിസ്റ്റ് ചെയ്യണ്ട ഡയറക്ടറി പേരാണെന്ന് കരുതി ls ഒഴിവാക്കിയതാണ്.. :)

      Delete
    5. അംഗീകരിക്കേണ്ടതാണ്. അതൊരു കീഴ്വഴക്കം ആണന്ന് പറഞ്ഞല്ലോ. പോസിക്സ് സ്പെസിഫിക്കേഷനില്‍ അത് പറയുന്നുണ്ടോ എന്ന് നോക്കണം..

      Delete
  6. //അവസാനമായി NULL എന്നത് സെന്റിനല്‍ ആര്‍ഗ്യുമെന്റ് അഥവാ സെന്റിനല്‍ എന്നറിയപ്പെടുന്നു. വ്യത്യസ്ത എണ്ണത്തിലുള്ള പരാമീറ്ററുകള്‍ സ്വീകരിക്കുന്ന ഫങ്ങ്ഷനുകളോട് ഇതാണ് അവസാനത്തെ പരാമീറ്റര്‍ എന്ന് സൂചിപ്പിക്കാന്‍ ഇവ ഉപയോഗിക്കുന്നു. (NULL എന്നത് സെന്റിനല്‍ അല്ല. അതിന് മറ്റ് ഉപയോഗങ്ങള്‍ ഉണ്ട്. ഇനി പരാമീറ്ററുകള്‍ ഇല്ല എന്നത് സൂചിപ്പിക്കാനായി ഉപയോഗിക്കുന്നവയെ ആണ് സെന്റിനല്‍ എന്ന് വിളിക്കുന്നത്. എക്സെക്ക് പ്രതീക്ഷിക്കുന്ന സെന്റിനല്‍ NULL ആണ്).//

    ഇവിടെ ആകെ ഒരു ആശയക്കുഴപ്പം

    ReplyDelete
    Replies
    1. ആശയക്കുഴപ്പം എന്താണെന്ന് മനസ്സിലായില്ല. വേരിയബിള്‍ ലെങ്ത് ആര്‍ഗ്യു‌‌മെന്റുകള്‍ ഉള്ള ചില ഫങ്ഷനുകള്‍ക്ക് അവ പ്രതീക്ഷിക്കുന്ന സെന്റിനല്‍ തന്നെ അവസാനത്തെ ആര്‍ഗ്യു‌‌മെന്റായി നല്‍കണം. ഇത്തരത്തിലുള്ള ഒരു ഫങ്ഷന്‍ ആണ് printf ഉം. എന്നാല്‍ അതിന് സെന്റിനലിന്റെ ആവശ്യമില്ല. ഞാന്‍ പറഞ്ഞു വന്നത് execl ഫങ്ഷന്റെ സെന്റിനല്‍ ആണ് NULL എങ്കിലും NULL എന്നതിന് എപ്പോളും സെന്റിനല്‍ എന്ന് അര്‍ഥമില്ല എന്നാണ്.

      Delete
    2. ok ഇപ്പോ ക്ലിയർ ആയി

      Delete