செமாஃபோர் (நிரலாக்கம்)

கணினியியலில் சேமாஃபோர் என்பது ஒரு பாதுகாக்கப்பட்ட மாறுபாட்டு தன்மைகொண்ட அல்லது ஒரு திட்டவட்டமான உருவமற்ற தரவு வகையாகும், இது இணையான புரோகிராமிங் சூழலில் நினைவக பகிர்வு (shared memory) போன்ற பகிர்வு ஆதாரங்களை (shared resources) அணுகுவதைக் கட்டுப்படுத்தும் ஒரு பழைய முறையைக் கொண்டிருக்கிறது. ஒரு கவுண்டிங் சேமாஃபோர் என்பது ஒரேயொரு ஆதாரத்தின் பூட்டப்பட்ட/பூட்டப்படாத ஃபிளாகாக (flag) மட்டும் இல்லாமல், இருக்கும் அனைத்து ஆதாரங்களுக்கான ஒரு கவுண்டராகவும் இருக்கிறது. இதனைக் கண்டுபிடித்தவர் எட்ஸ்ஜர் டிஜ்ஸ்ட்ரா ஆவார்.http://www.cs.utexas.edu/users/EWD/transcriptions/EWD01xx/EWD123.html E. W. Dijkstra, Cooperating sequential processes. டெக்னாலஜிக்கல் பல்கலைக்கழகம், ஈய்ண்டஹோவன், நெதர்லாந்து, செப்டம்பர் 1965.
சேமாஃபோர்கள் ஆதாரங்களின் முட்டுக்கட்டையைத் (deadlock) தடுப்பதில்லை என்றாலும் கூட, வெற்று தத்துவவாதிகளின் சிக்கல்களில் இருக்கும் போட்டி நிலைமைகளைத் தடுப்பதில் ஒரு சிறந்த தீர்வாக இருக்கின்றன.

 முன்னுரை 

கீழ்க்கண்ட செய்முறைகளைப் பயன்படுத்தி மட்டுமே சேமாஃபோரை அணுக முடியும். கீழே விளக்கப்பட்டிருக்கும் காரணங்களுக்காக அட்டாமிக்காக (atomic) குறிக்கப்பட்டிருப்பவை இடைமறிக்கப்படக் கூடாது, அதாவது இந்த புரோகிராமைச் செய்வதற்கு இது செயல்பட்டுக் கொண்டிருக்க வேண்டும் என்று அமைப்பு முடிவு செய்திருந்தால், அந்த செயல்முறைக்கு இடையில் அது இடைமறிக்கப்படக்கூடாது.

 procedure V (S : Semaphore);
 begin
 (சேமாஃபோர் விவாதத்தின் மதிப்பில் ஒன்றை அதிகரிக்கிறது; 
 இந்த அதிகரிப்பு ஒரு மாற்ற முடியாத செயல்முறையாக ஆகும், அதாவது அட்டாமிக் ஆகும்.*)
 S := S + 1;
 end;

 procedure P (S : Semaphore);
 begin
 (*சேமாஃபோர் அதன் மதிப்பில் ஒன்றைக் குறைக்கிறது
 இறுதி மதிப்பு எதிர்மறையாக இல்லாத வகையில், உடனடியாக இவ்வாறு குறைத்துவிடுகிறது. இந்த ெயல்முறையும் ஒரு மாற்ற முடியாத செயல்முறையாக ஆகும், அதாவது அட்டாமிக் ஆகும். *)
 repeat
 Wait();
 until S > 0;
 S := S - 1;
 end; 

மாறுபடும் S இன் அதிகரிப்பு இடைமறிக்கப்படக் கூடாது என்பதையும், S என்பது பூஜ்ஜியத்தை விட அதிகமாக இருந்தால், P செயல்முறையும் இடைமறிக்கப்படக் கூடாது என்பதையும் கவனிக்கவும். பிற செயல்முறைகள் செயல்பாட்டிற்கு வருவதைத் தடுக்க டெஸ்ட்-அண்ட்-செட் (ஆர்க்கிடெக்சரின் நெறிமுறைக் கட்டளைத் தொகுப்பு இதற்கு ஏற்றதாக இருந்தால் மட்டும்) அல்லது (யூனிபுரோசஸர் அமைப்புகளில்) இடைமறிப்புகளைத் (interrupts) தவிர்ப்பது போன்ற சிறப்புக் குறிப்புகளைப் பயன்படுத்தி இதைச் செய்யலாம்.

செயல்பாட்டில் இல்லாத ஆதாரங்களின் எண்ணிக்கையே சேமாஃபோரின் எண்ணிக்கை மதிப்பாகும். (ஒரேயொரு ஆதாரம் மட்டும் இருந்தால், 0 அல்லது 1 என்ற மதிப்புகளுடன் ஒரு "பைனரி சேமாஃபோர்" பயன்படுத்தப்படுகிறது) ஓர் ஆதாரம் கிடைக்கும் வரை P செயல்பாடு உறக்கநிலையில் (அதாவது தன்னுடைய முறையைக் கொண்டு வரவேண்டாம் என்று அமைப்பிற்குச் சொல்லிவிடும்) இருக்கும் அல்லது நெருக்கடி-காத்திருப்பு (எதையும் செய்யாமல் அதன் முறை வரும் வரை காத்திருக்கும்) நிலையில் இருந்து உடனடியாக ஓர் ஆதாரத்தைக் கோரும். V செயல்பாடு இதற்குத் தலைகீழானாது; ஒரு செயல்பாடு ஆதாரத்தைப் பயன்படுத்தி முடித்த உடனேயே இது அந்த ஆதாரம் கிடைத்திருப்பதை எடுத்துக்காட்டும். இந்த P மற்றும் V செயல்பாடுகள் அட்டாமிக் ஆனவை, அதாவது இந்தச் செயல்பாடுகளில் ஏதாவதொன்றின் போது அதே சேமிப்போரில் வேறு நடவடிக்கைகளைச் செயல்படுத்த எந்தச் செயல்முறையும் இடையில் குறுக்கிட முடியாது.

அடிப்படை பெயர்களான P மற்றும் V ஆகியவை டச் வார்த்தைகளின் துவக்க எழுத்தில் இருந்து வருகின்றன. V என்பது வெர்ஹோஜென் (verhogen), அல்லது "அதிகரிப்பு" என்பதாகும். P என்பதற்கு ("பரிசோதிப்பதற்கான"Silberschatz, Galvin, & Gagne 8th Ed. p.234 என்பதற்கான புரோபெரென், "அனுப்பு" என்பதற்கான பஸ்ஸீர், "முயற்சி செய்" என்பதற்கான ப்ரோபீர் மற்றும் "பறி" என்பதற்கான பேக்கென் உட்பட) பல்வேறு விளங்கங்கள் அளிக்கப்படுகின்றன, ஆனால் உண்மையில் டிஜிக்ட்ஸ்ரா, கருத்தளவில் "குறைப்பதற்கு முயற்சி செய்" என்ற பொருளில் அல்லது "சரிவுக்குக் கொண்டு வர முயற்சி செய்" என்ற வேறு சொல்லுக்கு இணையாக வரும் probeer te verlagen என்பதன் சுருக்கமான புரோலேங்க் http://www.cs.utexas.edu/users/EWD/ewd00xx/EWD74.PDF என்ற சொல்லுக்காக P என்பதை தாம் எடுத்தாண்டதாக எழுதினார்.http://www.cs.utexas.edu/users/EWD/transcriptions/EWD00xx/EWD51.html MULTIPROGAMMERING EN DE X8 from the E.W. Dijkstra Archive (in Dutch)டிஜிக்ஸ்டிராவின் சொந்த மொழிபெயர்ப்பே "ட்ரை- அண்ட் -டிக்ரீஸ்" என்று குறிப்பிடுகிறது, இந்தச் சொல்  கொச்சையான "ட்ரை-அண்ட்..." என்ற சொல்லாகத் தெரியாதவர்களுக்கு மிகுந்த குழப்பத்தை ஏற்படுத்தும் என்ற போதிலும் அவர் இதைப் பயன்படுத்துகிறார்.http://lkml.org/lkml/2005/12/19/34 Linux Kernel Mailing List: [PATCH 1/19] MUTEX: Introduce simple mutex implementationஅதிகரிப்பது, குறைப்பது இரண்டுமே டச் மொழியில் V என்ற எழுத்தில் தொடங்குவதால் குழப்பம் ஆரம்பித்துவிடுகிறது, அதேசமயம் அந்த வார்த்தையை முழுவதுமாக உச்சரிப்பதும் டச் மொழி தெரியாதவர்களுக்குச் சாத்தியப்படாத வகையில் குழப்பக்கூடும்.

புரோகிராமிங் மொழியான ALGOL 68 லும், லினக்ஸ் கெர்னலிலும் மற்றும் சில ஆங்கில பாடப்புத்தகங்களிலும், P மற்றும் V செயல்பாடுகள் முறையே கீழ் மற்றும் மேல் என்று அழைக்கப்படுகின்றன. மென்பொருள் பொறியியல் பயிற்சியில், பொதுவாக இவை காத்திரு மற்றும் சமிக்கை அல்லது பெறு மற்றும் விடு (இதை நிலையான ஜாவா லைப்ரரி பயன்படுத்துகிறது)) அல்லது தேங்கு மற்றும் அனுப்பு என்று அழைக்கப்படுகிறது. உண்மையான டச் எழுத்துகளுக்குப் பொருந்தி வரும் வகையில், சில புத்தகங்கள் வாங்கு மற்றும் வெளியேறு என்று அவற்றைக் குறிப்பிடுகின்றன.

நெருக்கடி-காத்திருப்பைத் தவிர்க்க, சேமாஃபோர் செயல்பாடுகளின் ஒரு இணைப்பு வரிசையைக் (வழக்கமாக முதலில் வருபவர் முதலில் செல்லலாம் என்ற பாணியில்) கொண்டிருக்கக் கூடும். பூஜ்ஜியம் மதிப்பைக் கொண்டிருக்கும் சேமாஃபோரில் ஒரு செயல்முறை P நடவடிக்கையைச் செய்கிறது என்றால், அந்தச் செயல்பாடு சேமாஃபோரின் வரிசையில் சேர்க்கப்படும். மற்றொரு செயல்பாடு V நடவடிக்கையைச் செய்து சேமாஃபோரை அதிகரிக்கும் போது, ஏற்கனவே அங்கு வரிசையில் செயல்பாடுகள் இருப்பதால், அவற்றில் ஒன்று வரிசையில் இருந்து நீக்கப்பட்டு செயல்படுத்தப்படும். செயல்பாடுகளுக்கு வெவ்வேறு முன்னுரிமைகள் இருக்குமானால், முன்னுரிமையின் அடிப்படையில் வரிசையில் அடுக்கப்படும், இதனால் அதிக முக்கியமான முன்னுரிமையில் இருக்கும் செயல்பாடு முதலில் வரிசையில் இருந்து எடுத்துக் கையாளப்படும்.

 ஒப்பீடு 

ஒரு பொது அறையில் இருக்கும் கழிவறைகளாக ஆதாரங்களையும், அந்தக் கழிவறைகளுக்குச் செல்ல காத்திருக்கும் நபர்களாக செயல்முறைகளையும், ஏதாவதொரு கழிவறைக்காக வரிசையில் நபர்கள் காத்திருக்கிறார்கள் அல்லது ஏற்கனவே அவர்கள் கழிவறையைப் பயன்படுத்திக் கொண்டிருக்கிறார்கள் என்பதாக கற்பனை செய்து கொள்ளுங்கள். கழிவறைக்கு வெளியில் உட்கார்ந்திருக்கும் ஒரு நபர், அந்த சமயத்தில் எத்தனை கழிவறைகள் காலியாக இருக்கின்றன, யார் அடுத்ததாக போக வேண்டும் என்று தீர்மானிக்கிறார்.

காலியாக இருக்கும் கழிவறைகளின் எண்ணிக்கை தான், சேமாஃபோரின் மதிப்பு, இது காலியாக இருக்கும் ஆதாரங்களைக் (கழிவறைகளை) குறிக்கிறது. ஒரு செயல்பாடு (நபர்) கழிவறையை அணுக வேண்டுமானால், சேமாஃபோரானது (பொறுப்பாளர்) வரிசையில் காத்திருக்க வேண்டுமா அல்லது காலியாக இருக்கும் கழிவறையைப் பயன்படுத்தலாமா என்று கூறுவார். கழிவறை காலியாக இருந்தால் அதில் நுழைய நபருக்கு (செயல்பாட்டிற்கு) வாய்ப்பு கிடைக்கும், பிறகு கழிவறைகளின் எண்ணிக்கையில் ஒன்று குறையும் (P அல்லது கீழ் செயல்பாடு போல). அதாவது காலியாக இருக்கும் ஆதாரங்களின் எண்ணிக்கையில் 1 குறைந்துவிட்டது என்பதை இது குறிக்கிறது. காலியாக இருக்கும் கழிவறைகளின் எண்ணிக்கை பூஜ்ஜியம் என்றால், காலியாகும் வரை நபர் (செயல்முறை) வரிசையில் இருக்க வேண்டும் (அதாவது, S>0 என்று ஆகும் வரை செயல்முறை உறக்கநிலையில் இருக்க வேண்டும்). ஒரு நபர் கழிவறையைப் பயன்படுத்தி முடித்துவிட்டால் (செயல்பாடு ஆதாரத்துடனான அதன் வேலையை முடித்துக் கொள்கிறது), அடுத்த நபர் அதைப் பயன்படுத்திக் கொள்ளலாம். இது, காலியான கழிவறைகளின் எண்ணிக்கை அதிகரித்திருப்பதைக் குறிக்கிறது (இது V அல்லது மேல் செயல்பாடு என்பதைப் போல). இப்போது, S பூஜ்ஜியத்தை விட அதிகமாகி விடும். அதனால் காத்திருக்கும் நபர் (அதாவது, உறக்கநிலையில் இருக்கும் செயல்முறை) இந்த கழிவறையைப் (ஆதாரத்தை) பயன்படுத்திக் கொள்ளலாம்.

காலியாக இருக்கும் கழிவறைகளை விசாரிப்பது (ஆதாரம் காலியாக இருக்கிறதா என்று பரிசோதிக்கும் செயல்பாடு), காலியான கழிவறைகளின் (ஆதாரங்களின்) எண்ணிக்கையை மீண்டும் மீண்டும் குறிப்பிடுவது, வரிசையில் காத்திருப்பது போன்ற செயல்பாடுகள் மற்ற செயல்பாடுகளால் தொந்தரவு செய்யப்படக்கூடாது. இது தான் அட்டாமிக் நடவடிக்கை என்றழைக்கப்படுகிறது.

இந்த வரிசையானது முதலில் வருபவர் முதலில் வெளியில் செல்லலாம் என்ற அடிப்படையில் இருக்கும், அதாவது வரிசையில் முதலில் இருக்கும் நபருக்கு முதலில் காலியாகும் கழிவறையைப் பயன்படுத்த வாய்ப்பளிக்கப்படும். இருந்தாலும் கூட, வரிசையில் எங்கோ நிற்கும் ஒருவர் அவசரமாக பயன்படுத்த விரும்பினாலும் இந்த வரிசை மாற்றி அமைக்கப்படலாம் (அதாவது, செயல்பாடு அதிக முன்னுரிமை பெற்றிருந்தால் மாற்றி அமைக்கப்படும்).

கவுண்டிங் சேமாஃபோர் கருத்தை, சேமாஃபோரில் இருந்து ஒரு 'யூனிட்டிற்கு' மேலாக ஏறும் அல்லது திரும்பும் திறனுடன் விரிவுபடுத்தலாம். இவ்வாறுதான் சேமாஃபோர் யூனிக்ஸ் இயங்கு தளத்தில் வேலை செய்கிறது. மாற்றி அமைக்கப்பட்ட P மற்றும் V செயல்பாடுகள் பின்வருமாறு வேலை செய்கின்றன:

 procedure P (S : Semaphore; I : Integer);
 begin
 (* மொத்த செயல்பாடும் அட்டாமிக் ஆகும்*)
 S >= 1 என்று வரும் வரை திரும்ப திரும்ப செய்யவும்;
 S := S - I
 end;

 procedure V (S : Semaphore; I : Integer);
 begin
 S := S + I (* அட்டாமிக் செயல்பாடு *)
 end;

 இன்று புரோகிராமர்களால் பயன்படுத்தப்படும் சேமாஃபோர்கள் 

பொதுவாக வேறு எந்த வகையான ஒத்தியக்கத்திற்கு இயல்பாகவே பொருந்தி வராத புரோகிராமிங் மொழிகளில் சேமாஃபோர் பயன்படுத்தப்பட்டு வருகிறது. பெரும்பாலான இயங்கு தளங்களில் இவை ப்ரிமிட்டிவ் சின்க்ரோனைசேசன் இயங்குமுறையாக இருக்கின்றன. புரோகிராமிங் மொழி விரிவாக்கத்தில் இருக்கும் போக்கு, கணினித்திரை போன்ற ஒத்தியக்கத்திற்கு சிறந்த கட்டமைப்பு வடிவத்தில் இருக்கிறது (இருந்தாலும், இந்த நவீன கட்டமைப்புகள் சேமாஃபோர்களை திரைக்குப் பின்னால் இருந்து தான் பயன்படுத்துகின்றன). (மல்டி-ரிசோர்ஸ்) முட்டுக்கட்டைகளுடன் செயல்படும் போது இருக்கும் அவற்றின் செயல்திறமின்மையோடு கூட, புரோகிராமர்களின் ஒருசில சிறிய தவறுகளிலும் அவை புரோகிராமர்களைக் கைவிட்டுவிடுகின்றன, அதாவது ஒரு செயல்முறையில் ஏற்கெனவே கையாளப்பட்டு வரும் ஒரு சேமாஃபோரை அதிலிருந்து நீக்குவது மற்றும் நீக்கப்பட்ட சேமாஃபோரை மீண்டும் வெளியிடுவதற்கு மறந்துவிடுவது போன்ற சிறிய தவறுகளிலும் புரோகிராமர்களை இவை கைவிட்டுவிடுகின்றன.

 உதாரண பயன்பாடு 

சேமாஃபோருடன் எண்கள் இணைந்திருப்பதால், பல இழைகள் (threads) புறநிலையில் இருந்து ஒத்துழைப்பைப் பெற வேண்டிய போது அவை நிறுவப்படுகின்றன. பின்வரும் உதாரணத்தை கவனியுங்கள்:

A என்ற இழைக்கு, அது செயல்படுத்தப்படுவதற்கு முன்னால் இரண்டு தரவுத்தளங்களிலிருந்து தகவல்கள் தேவைப்படுகிறது. இந்த தரவுத்தளங்களை அணுகுவதற்கான கட்டுப்பாடு B, C ஆகிய வெவ்வேறு இழைகளால் கையாளப்படுகின்றன. இந்த இரண்டு இழைகளும் ஒரு தகவல்-செயல்முறையாக்க முழுச்சுற்றைக் (லூப்பைக்) கொண்டிருக்கின்றன; இந்தத் தரவுத்தளங்களில் ஏதாவது ஒன்றை கையாள வேண்டிய தேவை ஏற்படும்போது, அந்தக் குறிப்பிட்ட இழையின் தகவல் வரிசையில் ஒரு செய்தி அனுப்பப்படும். இழை A, சேமாஃபோர் S என்பதை init (S,-1) என்பதுடன் துவக்கிவிடுகிறது. பிறகு A ஒரு தகவல் கோரிக்கையையும், சேமாஃபோர் Sக்கான ஒரு குறிப்பாணையும் இணைத்து B மற்றும் Cவுக்கு அனுப்புகிறது. பிறகு A ஆனது P(S)ஐ அழைக்கிறது, அது தடுக்கிறது. இதற்கிடையில் மற்ற இரண்டு இழைகளும் தகவல்களைப் பெறுவதற்கான அவற்றின் நேரத்தைப் பெறுகின்றன; ஒவ்வொரு இழையும் அவற்றின் தகவல்களைப் பெற்று முடித்தபோது, அது அனுப்பப்பட்ட சேமாஃபோரில் V(S)ஐ அழைக்கிறது. இரண்டு இழைகளும் முடிந்த பிறகு மட்டுமே, சேமாஃபோரின் மதிப்பு நேர்மறையாக இருக்கும், அத்துடன் அதன்பிறகு தான் A இழையினால் தொடர முடியும். இவ்வாறு பயன்படுத்தப்படும் சேமாஃபோர், ஒரு "கவுண்டிங் சேமாஃபோர்" என்று அழைக்கப்படுகிறது.

ஒரு கவுண்டிங் சேமாஃபோருக்கு அப்பாற்பட்டு, பிளாக்கிங் சேமாஃபோர் என்பதும் ஒன்று உண்டு. ஒரு பிளாக்கிங் சேமாஃபோர் என்பது, பூஜ்ஜியத்தில் துவக்கப்படும். சேமாஃபோர் பிளாக்குகளில் P செயல்பாட்டைச் செய்யும் எந்தவொரு இழையின் மீதும் இதன் தாக்கம் இருக்கும்.

 வன்பொருள் ஒத்துழைப்பு 

பொதுவாக, தேவைப்படும் பின்புல மறைவு செயல்பாடுகளைச் (automicity operations) செய்ய சேமாஃபோரின் பயன்பாட்டிற்கு வன்பொருள் ஒத்துழைப்பு தேவைப்படுகிறது. பெரும்பாலும், தகவல் குறியீடுகளைக் (instructions) கொண்டிருக்கும் கணினி இயந்திர மொழிகள் குறிப்பாக சேமாஃபோர்களை மனதில் வைத்தே வடிவமைக்கப்பட்டு இருக்கின்றன. இந்தச் சிறப்புத் தகவல் குறியீடுகள் நினைவகத்திற்கு ஒரு ரீட்-மாடிஃபை-ரைட் சுழற்சியைக் (read-modify-write cycle) கொண்டு செல்கின்றன, இவை தடையில்லாமல் இருப்பது மட்டுமில்லாமல், பிற புரோசஸர்கள் அல்லது உள்ளீட்டு/வெளியீட்டு சாதனங்களால் அதே நினைவக இடத்தில் நடைபெறும் ஏனைய எல்லா செயல்பாடுகளையும் தவிர்த்துவிடுகிறது. இந்தச் சிறப்புத் தகவல் குறியீடுகள் பயன்படுத்தப்படும் சேமாஃபோர் வழிமுறை சோதனைச் செய்வதையும், ஒரு சேமாஃபோரை ஒரே அட்டாமிக் செயல்பாட்டில் மாற்றுவதற்கும் உத்திரவாதம் அளிக்கிறது.

 பைனரி சேமாஃபோரும், மியூடெக்சும் 

ஒரு மியூடெக்ஸ் என்பது பைனரி சேமாஃபோர் (அதாவது, 1-இன் திறனுடன் கூடிய ஒரு சேமாஃபோர்) ஆகும், வழக்கமாக உரிமைஉடைமை (ownership), பாதுகாப்பு அல்லது மீள்சுழற்சி (recursivity) ஆகியவற்றிற்கு ஏற்ப முன்னுரிமை மாற்றி அளிப்பது போன்ற சிறப்பு வசதிகளையும் உள்ளடக்கி இருக்கும். மியூடெக்ஸ் மற்றும் சேமாஃபோர் இரண்டிற்கும் இடையிலான வேறுபாடுகள் இயங்குதள அமைப்பைச் சார்ந்திருக்கிறது, இருந்தாலும் மியூடெக்ஸ்கள் சிறப்பார்ந்த மற்றும் விரைவான செயல்பாடுகளுக்காக நிறுவப்படுகின்றது. மியூடெக்ஸ்கள் பரஸ்பர விடுபாட்டிற்காக (mutual exclusion) (போஸ்ட்/ரிலீஸ் செயல்முறை இழைக்கு மறுக்கப்படுவது பெண்ட்/அக்யூர் என்று அழைக்கப்படுகிறது) மட்டுமே உரியவை என்றும், பைனரி சேமாஃபோர்கள் நிகழ்வு அறிவிப்புகளை (event notification) (எந்தவித இழையிலிருந்தும் எடுக்கும் முன்கூட்டிய திறன்) காட்டுவதற்கானவை என்று கருதப்படுகின்றன.

 குறிப்புகள் மற்றும் குறிப்புதவிகள் 


 The Little Book of Semaphores , by ஆலன் பி. டௌனி, க்ரீன் டீ ப்ரஸ்.

 பிற வலைத்தளங்கள் 
 Over Seinpalen (EWD 74), இதில் டிஜிக்ஸ்டிரா அந்தக் கருத்தை (டச் மொழியில்) வெளியிடுகிறார்
 semaphore.h programming interface - The Open Group Base Specifications Issue 6, IEEE Std 1003.1
 The Little Book of Semaphores, ஆசிரியர் ஆலன் பி. டௌனி
 A pragmatic, historically oriented survey on the universality of synchronization primitives, by Jouni Leppäjärvi

பகுப்பு:கூகுள் தமிழாக்கம்-கணினியியல்