תכנות מרובה נימים

Download Report

Transcript תכנות מרובה נימים

‫‪Multithreading‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪ Thread‬הוא רצף של פעולות שמתבצעות‬
‫באופן עצמאי במטרה לבצע משימה מסוימת‬
‫(ספר לימוד בגאווה מאת חיים מיכאל )‬
‫נים נוצר כאובייקט של מחלקה היורשת‬
‫למחלקה ‪Thread‬‬
‫שיטה )(‪ run‬מממשת אלגוריתם של משימת‬
‫הנים‬
‫)(‪ Start‬הפעלת נים‪.‬‬
‫‪ ‬אפשר להסביר ביצועי תוכנית רב‪ -‬נימים‬
‫כהתפצלות המחשב למספר ‪Virtual‬‬
‫‪Java Machine‬‬
‫יתרונות וחסרונות של תוכנית רב נימים‬
‫תזמון נימים נגשים למשאב אחד משותף‪.‬‬
Thread ‫יצירת‬
public class CounterThread extends Thread
}
private Counter c ;
public CounterThread( String Name,Counter c)
{
super.setName(Name);
this.c = c;
};
public void run()
{
c.something();
}
}
‫ מייצג משאב משותף למספר נימים‬Counter ‫ מסוג‬c ‫שדה‬
Count ‫ מחלקה‬: ‫משאב משותף‬
public class Counter {
private int count = 0;
public void something()
{
int limit = count + 50;
while( count != limit ) {
System.out.println("Thread:"+
Thread.currentThread().getName() + "
Count:" + count+ " Limit: "+ limit );
count++;
};
}
}
50 ‫ של מחלקה אמורה לבצע לולאה‬something ‫שיטה‬
‫פעמים תוך כדי הדפסת שם נים‬
.‫המשתמש במשאב בכל עת הנתון‬
public class Applic
{
public static void main(String[] args)
{
Counter c = new Counter();
CounterThread ct1 = new CounterThread("David",c);
CounterThread ct2 = new CounterThread("Shmuel",c);
ct1.start(); ct2.start();
}
}
ct1, : ‫ ושני נימים‬Counter ‫ יוצרת אובייקט‬main ‫שיטה‬
ct2
.‫ומפעילה אותם‬
‫ שורות הדפסה של נים‬50 ‫האם פלט הצפוי הוא שילוב של‬
?‫ שורות של הדפסה של נים השני‬50 -‫ראשון ו‬
‫פלט מעיד על לולאה אין סופית‬
? ‫סיבה‬
‫סיבות לולאה אין סופית‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫במחשב עם מעבד אחד‬
‫תכנות‬
‫‪multithreading‬‬
‫ממומשת‬
‫דרך חלוקת זמן המעבד‬
‫בין נימים‬
‫שיטה ‪something‬‬
‫מופעלת בו‪-‬זמנית ע"‬
‫מספר נימים‬
‫ביצוע שיטה‬
‫‪ something‬אינו מובטח‬
‫מהתחלה ועד סוף השיטה‬
‫ע" נים אחד‪.‬‬
‫ביצוע שיטה‬
‫‪ something‬יכולה‬
‫להיות הופסק בכל רגע‬
‫לטובת נים אחר‬
synchronized ‫מאפיין‬
synchronized ‫אפשר להגן קטע קוד קריטי ע" שימוש במאפיין‬
. Counter ‫הנה גרסא חדשה של מחלקה‬
public class Counter1
{
private int count = 0;
public synchronized void something()
{
int limit = count + 50;
while( count != limit ) {
System.out.println("Thread:"+
Thread.currentThread().getName() + " Count:" +
count+ " Limit: "+ limit );
count++;
};
}
}
synchronized ‫מאפיין‬
‫ וכך מסייע לנים הנוכחי‬,‫אינו מאפשר לשום נים להפסיק ביצוע קטע מוגן‬
something ‫לבצע שיטה‬
‫עד סוף הקטע מוגן מבלי להיות הופסק ע" נים אחר‬
‫‪Producer- Consumer‬‬
‫‪model‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫תוכנה רבת נימים‬
‫מחסן – משאב משותף לכל נימים‬
‫יצרן ( ‪ ) Producer‬יוצר "מוצר"‬
‫ומאחסן אותו בתוך מחסן‬
‫צרכן ( ‪ ) Consumer‬ראשי להוציא‬
‫"מוצר" מהמחסן אך ורק כאשר הוא‬
‫מאוחסן ע" יצרן‬
‫זמן "יצור" אינו ידוע מראש‪ ,‬יכול גם‬
‫להשתנות‬
‫באקראי‬
‫יצרן‬
‫מחסן ‪>-----‬‬
‫יצרן‬
‫יצרן‬
‫יצרן‬
‫מחסן ‪>-----‬‬
‫יצרן‬
‫יצרן‬
‫‪1‬‬
‫‪2‬‬
‫‪1‬‬
‫יצרן‬
‫מחסן ‪>-----‬‬
‫‪1‬‬
‫‪2‬‬
‫‪1‬‬
‫צרכן‬
‫ממתין‬
‫צרכן‬
‫צרכן‬
‫צרכן‬
‫צרכן‬
‫מחלקה ‪ ( Store‬מחסן )‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫אובייקט המייצג מחסן‪ -‬הוא משאב משותף‬
‫למספר נימים‪.‬‬
‫מחלקה מאפשרת שימוש בשתי פעולות ‪ Set‬ו‪-‬‬
‫‪ .Get‬אובייקט מסוג ‪ Producer‬משתמש בשיטה‬
‫‪,Set‬‬
‫אובייקט מסוג ‪ Consumer‬משתמש בשיטה‬
‫‪Get‬‬
‫שתי שיטות האלה בעלות מאפיין‬
‫‪ synchronized‬כלומר‪ :‬אך ורק נים אחד מקבל‬
‫זכות להפעיל את השיטות האלה בכל פסק זמן‪.‬‬
‫תזמון נימים מתבצע ע" פעולות ‪ wait‬ו –‬
‫‪.notify‬‬
‫‪.‬‬
wait- notify : ‫תזמון נימים ע" פעולות‬
Set( int Value , int Code)
flag <- false
If( flag)
No
Yes
wait
values[code]<-Value
flag<-true
notify
–
Value

‫ – קוד יצרן‬Code

‫ערך המיועד לאחסון‬
wait- notify : ‫תזמון נימים ע" פעולות‬
Get( int Code)
‫ – קוד יצרן‬Code
"‫ ע‬store -‫פעולה מחזירה ערך המאוחסן ב‬
Code '‫נים מס‬
If( !flag)
No
Yes
wait
return
values[code]
flag<-false
notify


Producer
import java.util.*;
public class Producer extends Thread
{
private int code ;
private Store s;
public Producer(int Code, Store s ) {
code =Code;
this.s= s;
this.setName("Producer: " + code);
};
public void run()
{
Random rnd = new Random();
int N= 10; // ‫מספר שלבי יצור‬
while(N-- >0)
{
int limit= rnd.nextInt(1000000);
for( int i=0; i<limit;i++); // dummy loop
s.Set(limit, code);
}
}
}
Consumer
mport java.util.*;
public class Consumer extends Thread
{
private int code ;
private Store s;
public Consumer(int Code, Store s )
{
code =Code;
this.s= s;
this.setName("Consumer: " + code);
};
public void run()
{
Random rnd = new Random();
int N=10; // ‫מספר שלבי יצור‬
while(N-- > 0){
int limit= rnd.nextInt(1000000);
for( int i=0; i<limit;i++); // dummy loop
s.Get(code);
}
}
}
Main
public static void main(String[] args) {
int N=3; // ‫מקומות אחסון‬
Store s= new Store(N);
Producer p[]= new Producer[N];
Consumer c[]= new Consumer[N];
for(int i=0; i<N; i++)
{
p[i]= new Producer(i,s);
c[i]= new Consumer(i,s);
};
for( int j=0; j<N; j++)
{
c[j].start() ;
};
for( int k=N-1; k>=0; k--)
p[k].start();
}