1 / 11

סמפורים

סמפורים. סמפורים כלליים. סמפור ממומש ב- Linux Threads בערך כמו שתואר בהרצאה: לכל סמפור יש מונה, תור ומנעול שתפקידו להגן על הקוד של הפעולות של הסמפור (  פעולות אטומיות) שתי פעולות בסיסיות על הסמפור: wait : אם המונה גדול מ-0, מקטינה אותו ב-1, אחרת החוט נכנס להמתנה בתור.

kael
Download Presentation

סמפורים

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. סמפורים

  2. סמפורים כלליים • סמפור ממומש ב-Linux Threadsבערך כמו שתואר בהרצאה: • לכל סמפור יש מונה, תור ומנעול שתפקידו להגן על הקוד של הפעולות של הסמפור (פעולות אטומיות) • שתי פעולות בסיסיות על הסמפור: • wait: אם המונה גדול מ-0, מקטינה אותו ב-1, אחרת החוט נכנס להמתנה בתור. • post: אם תור הממתינים לא ריק, מוציאה ומעירה את החוט הראשון בתור, אחרת מגדילה את המונה ב-1 • בהרצאה קראנו ל-postבשם signal. • תור הממתינים הוגן (FIFO) לפי עדיפויות, כלומר חוט בעדיפות גבוהה יצא מהתור לפני חוט בעדיפות נמוכה

  3. פעולות על סמפורים (1) #include <pthread.h> #include <semaphore.h> • אתחול סמפור לפני השימוש: int sem_init(sem_t *sem, int pshared, unsigned int value); • פינוי סמפור בתום השימוש: int sem_destroy(sem_t *sem);

  4. פעולות על סמפורים (2) • ביצוע waitעל סמפור: int sem_wait(sem_t *sem); • ביצוע postעל סמפור: int sem_post(sem_t *sem); • גרסה לא-חוסמת של wait: int sem_trywait(sem_t *sem); • אם המונה של הסמפור אינו גדול מ-0, חוזרת מיד ונכשלת • קריאת ערך מונה הסמפור: int sem_getvalue(sem_t *sem, int *sval);

  5. פעולות על סמפורים (3) • פרמטרים: • sem – הסמפור עליו מבוצעות הפעולות. • pshared – אם ערכו גדול מ-0, מציין שהסמפור יכול להיות משותף למספר תהליכים. תכונה זו אינה נתמכת, ולכן נציב בו 0 קבוע. • value – ערכו ההתחלתי של מונה הסמפור. • sval – מצביע למקום בו יאוחסן ערך מונה הסמפור. • ערך מוחזר: 0 בהצלחה, (1-) בכישלון • הפונקציות sem_wait()ו-sem_getvalue()תמיד מצליחות.

  6. הערות על סמפורים • סמפור המאותחל עם מונה בערך 1 נקרא סמפור בינארי. • סמפור בינארי יכול לשמש להגנה על קטע קריטי (ליצור מניעה הדדית בין החוטים הניגשים). • סמפור בינארי אינו מנעול mutex, משום שכל חוט יכול לבצע postעל סמפור, גם אם לא ביצע waitעל הסמפור קודם לכן (אין "בעלות" על הסמפור), כמו גם עוד הבדלים מינורים.

  7. סמפור בינארי #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <semaphore.h> #define NITER 1000000000 sem_t sema; long count = 0; void * ThreadAdd(void * a) { for(long i = 0; i < NITER; i++) { sem_wait( &sema); count++; sem_post( &sema); } } int main(int argc, char * argv[]) { pthread_t tid1, tid2; sem_init(&sema,0,1); pthread_create(&tid1, NULL, ThreadAdd, NULL); pthread_create(&tid2, NULL, ThreadAdd, NULL); pthread_join(tid1, NULL); /* wait for the thread 1 to finish */ pthread_join(tid2, NULL); /* wait for the thread 2 to finish */ if (count < 2 * NITER) printf("\n BOOM! count is [%ld], should be %ld\n", count, 2*NITER); else printf("\n OK! count is [%ld]\n", count); sem_destroy(&sema); pthread_exit(NULL); } OK! count is [2000000000]

  8. סמפור בינארי #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <semaphore.h> #define NITER 1000000000 sem_t mutex; long count = 0, count1 = 0; void * ThreadAdd(void * a) { for(long i = 0; i < NITER; i++) { sem_wait( &mutex ); count++; sem_post( &mutex ); } for(i = 0; i < NITER; i++) count++; } int main(int argc, char * argv[]) { pthread_t tid1, tid2; sem_init(&mutex,0,1); pthread_create(&tid1, NULL, ThreadAdd, NULL); pthread_create(&tid2, NULL, ThreadAdd, NULL); pthread_join(tid1, NULL); /* wait for the thread 1 to finish */ pthread_join(tid2, NULL); /* wait for the thread 2 to finish */ if (count < 2 * NITER) printf("\n BOOM! count is [%ld], should be %ld\n", count, 2*NITER); else printf("\n OK! count is [%ld]\n", count); if (count < 2 * NITER) printf("\n BOOM! count1 is [%ld], should be %ld\n", count1, 2*NITER); else printf("\n OK! count1 is [%ld]\n", count1); sem_destroy(&mutex); pthread_exit(NULL); } OK! count is [2000000000] BOOM! count1 is [16372624], should be 2000000000

  9. #include < stdio.h >#include < pthread.h >#include < semaphore.h >#include < signal.h >sem_t semname; int qval=1; void *func1(void *arg) { while(qval) {sem_wait(&semname);printf("Thread one prints # %d\n",(*(int *)(arg))++);sem_post(&semname);sleep(1);} }void *func2(void *arg) { while(qval) {sem_wait(&semname);printf("Thread two prints # %d\n",(*(int *)(arg))++);sem_post(&semname);sleep(1);} } void quit() { qval=0; }main() { int i=0;signal(SIGINT,quit); //ctrl+csem_init(&semname,0,1);pthread_t thread1,thread2;pthread_create(&thread1,NULL,func1,&i);pthread_create(&thread2,NULL,func2,&i);pthread_join(thread1,&i);pthread_join(thread2,&i);printf("\nQuiting...\n");return 0; }

  10. כעת נעבור לדוגמאות נוספות • דוגמאות השוואה • דוגמאות לסמפור שאינו בינארי

More Related