ארכיון

ארכיון לקטגוריה ‘כללי’

כך החזרתי מכשיר מייזו U20 תמורת סכום מלא

פוסט פחות בעניין תוכנה. אבל לפעמים שווה לשתף גם מכיוונים אחרים.

אמ;לק

קניתי סמארטפון מייזו U20, והצלחתי להחזיר ל״באג״ תמורת החזר כספי מלא, למעט פחת של 7%.

ולעניין עצמו

קניתי מכשיר מייזו, מדגם U20, לפני בערך חמישה חודשים. ניסיתי הפעם את הגישה של ״בוא נלך על משהו סיני עד 1000 ש״ח ונקווה לטוב״.

אז קניתי, והעברתי את כל הדברים והתקנתי את כל האפליקציות שאני משתמש בהן, והכל היה נראה נחמד.

עד ש..

הטלפון העיר אותי בערך חצי שעה מוקדם מדי.

זה גם ככה מבאס לקום בבוקר, אז חצי שעה מוקדם מדי, למה??

מכאן ואילך, התחיל המסע שלי להבין למה האפליקציה של השעון המעורר, שעשתה עבודה מצויינת במכשיר הקודם, לא עובדת כמו שצריך במייזו הזה.

תחנה ראשונה: גוגל

חיפושים ראשונים הראו שצריך להגדיר כל מיני הגדרות כדי שאפליקציה שעובדת ברקע, לא תעוף מה״רקע״ הזה.

אז הגדרתי. צריך להגיע לבערך 4 מסכי הגדרות שונים כדי להגדיר אפליקציה שתמשיך לחיות ברקע.

ושיניתי גם הגדרות גלובליות במכשיר (בגדול: להעדיף ביצועים על פני חיי סוללה).

ולצערי, זה לא עבד. כלום לא עבד. האפליקציה עדיין הופעלה מוקדם מדי.

והקטע הוא שהשעון המעורר המובנה במכשיר, שהוא לא אפליקציה צד שלישי, עובד מצוין. אבל אין לו פיצ׳רים כמו אפליקציה צד שלישי.

תחנה שניה: עוד אפליקציות

גם שעונים מעוררים אחרים, כולל זה של גוגל, לקו באותה בעיה: מעירים מוקדם מדי.

והאמת, לא רק שעונים מעוררים. כל אפליקציה של תזכורות, או יומן, או משהו שאמור לתת התרעה – לא עבד כמו שצריך. במיוחד אם שעת התזכורת היא למעלה משלוש שעות קדימה.

תחנה שלישית: התמיכה של ״באג״

אוי, ״באג״, ״באג״. באמת באג.

כמה שיחות עם התמיכה הטכנית ועם שירות הלקוחות שלהם, וכמה הם כשלו במתן תמיכה טכנית ובמתן שירות…

כמה מהבעיות של ״באג״:

הם מקליטים את השיחות, ומציינים את זה במפורש. אבל הם כנראה לא מתעדים בצורה אחרת את השיחה, ואז, אם נציג אחר עונה להמשך טיפול, הייתי צריך לספר לו (או לה) את כל הסיפור מהתחלה.

בנוסף לזה, כשביקשתי איזה מספר מזהה לפניה שלי לתמיכה הטכנית – לא היה כזה.

מסיבה זו בחרתי לעבור למיילים. זה אמנם דורש הרבה יותר זמן כדי לכתוב הכל, אבל לפחות יש תיעוד זמין.

כל פניה שלי לשירות הלקוחות של ״באג״ היא כזו של יחס מזלזל כלפי הלקוח. יוצא דופן הוא מנהל שירות הלקוחות הארצי (מיד ארחיב).

התחושה שקיבלתי היא שהם עונים לא לעניין, ופשוט מנסים בעקביות להתחמק מאחריות.

גם כאשר שלחתי את המכשיר לבדיקה במעבדה של ״באג״, הם החזירו אותו אלי מאופס לחלוטין, תוך טענה שהבעיה נפתרה ע״י שחזור הגדרות היצרן. אבל לא: שוב התקנתי את האפליקציה של השעון המעורר, והיא שוב העירה מוקדם מדי.

כשחזרתי אל ״באג״ עם הממצאים האלה, הם טענו (בנפנוף עדין), שהם לא מצליחים לראות את הבעיה במכשיר שיש להם. מכיוון שכך, מבחינתם הבעיה לא קיימת, ו״לפנים משורת הדין״ הם מוכנים לקבל את המכשיר שלי שוב למעבדה כדי להבין את הבעיה לעומק.

סליחה? ״לפנים משורת הדין״?

בנקודה הזו התעקשתי לשוחח עם מנהל שירות הלקוחות הארצי, כי הנציגה שטיפלה בי, אחת בשם הודיה, איך לומר, לא מומחית גדולה בשירות לקוחות.

כדי לשוחח עם מנהל שירות הלקוחות הארצי של ״באג״, מסתבר שלא מספיק לומר את זה בצורה ברורה ומפורשת בשיחה עצמה עם הודיה:
לא, אני צריך להיכנס לאתר של ״באג״, ושוב לשלוח פניה לשירות הלקוחות של ״באג״, ולציין שאני מעוניין לדבר עם רום כבודו מנהל שירות הלקוחות הארצי. ואחרי כל זה, כבודו יתפנה אלי תוך כך וכך ימי עסקים (לא זוכר כבר אם זה שני ימי עסקים או יותר).

וכך שירות הלקוחות של ״באג״ פועל: כל פניה זו התשה. גם על המייל הכי מנומק שכתבתי, שמסביר את מהות הבעיה, ואת כל הדרכים לפתרון שלא עזרו, התגובה שקיבלתי (מהודיה, אלא מה) חזרה על אחת הדרכים שכבר הציעו לי מהתמיכה הטכנית ושלא עזרה.
והכל עטוף במין ניסוחים שמסתיימים ב״תודה ויום טוב״. כאילו, חמודי, הבעיה נמצאת איפשהו אצלך, לא אצלנו.

ההתשה באה לידי ביטוי גם בזה שהנהלים חשובים יותר מהכל. רוצה לפנות למנהל? אז תמלא פניה מסודרת, והוא יחזור אליך תוך שני ימי עסקים.
ואם הבעיה לא נפתרה ואתה רוצה לפנות שוב למנהל? אז שוב תמלא פניה מסודרת, ונחש מה? הוא לא יחזור אליך בהקדם. לא, קח לך שני ימי עסקים ואז הוא יחזור אליך.

תחנה רביעית: ניצחתי את ״באג״

התעקשתי. והתעקשתי. רק כאשר תארתי למנהל את הבעיה, והסברתי לו (בדיוק כמו שגם הסברתי במיילים) איך אפשר לראות שהיא מתרחשת, איכשהו הם הצליחו שם ב״באג״ לראות שהבעיה אכן קיימת ומתרחשת! וואו!

אז הסכימו שאחזיר את המכשיר תמורת החזר מלא. לצערי, המכשיר כבר היה עם שריטה קטנה.

אחרי משא ומתן, סיכמנו שהשריטה היא 7% פחת, שזה אומר 70 ש״ח על חשבוני.

כמה ימים אחרי, החזרתי את המייזו הסורר לחנות, עם המטען והקופסה שלו, וקיבלתי החזר של 930 ש״ח.

מסקנות

  1. שווה להתעקש
  2. עדיף לעבוד במיילים מול תמיכה טכנית ומול שירות לקוחות, ככה יש תיעוד לכל דבר.
  3. אם יש למישהו מכשיר שכזה, הוא יכול בכיף להחזיר ל״באג״ ולקבל החזר, הבעיה עדיין קיימת
  4. אני, אישית, לא מתכוון לקנות ב״באג״ מכשיר שאולי אי פעם יצטרך תמיכה טכנית. התמיכה הטכנית שלהם עלובה, ושירות הלקוחות מזעזע.

ולמען הסר ספק, בבלוג הזה בכלל, ובפוסט הזה בפרט, אני כותב את דעותי האישיות בלבד.

קטגוריות:כללי, שופינג תגיות:

תור מקבילי – Concurrent Queue

28 יוני, 2009 3 תגובות

רוב המתכנתים מכירים מבני נתונים בסיסיים, כמו מערך, רשימה מקושרת, וגם תור ומחסנית. הבעיה מתחילה כשרציתי למקבל תור. כלומר, ליצור מחלקה עם התכונות של תור, לצד העובדה שיכולים לגשת אליה במספר ת'רדים במקביל (אני לא מת על התרגום ל"חוטים", ומי שרוצה לתת תרגום אחר – תעירו חופשי).

נשמע פשוט, נכון? כולה לעטוף תור קיים ומוכח בנעילה קטנה, ויש לך תור מקבילי.

אז זהו, שלא.

כדי להמחיש את העניין, הנה המימוש הנאיבי ("כולה לעטוף תור קיים" וכו' וגו') של תור מקבילי:

public class NaiveConcurrentQueue<T>
{
  private Queue<T> queue = new Queue<T>();

  public void Enqueue(T item)
  {
    lock (queue)
    {
      queue.Enqueue(item);
    }
  }

  public T Dequeue()
  {
    lock (queue)
    {
      return queue.Dequeue();
    }
  }
}

בכוונה אין כאן את כל המתודות והממברים של תור, רק את השתיים האלו, כי זאת רק דוגמה. אז כאמור, רק נעילה סביב כל מתודה/ממבר של התור הפנימי, ויש לנו מקבול. אבל חבר'ה חבר'ה, רגע רגע, מה זה בדיוק נעילה? (לא, מוטל, התפילה המסיימת ביום כיפור זה לא מה שהתכוונתי)

נעילה בקוד, או lock, זה סוג של מאקרו ברמת הקומפיילר, שמאפשר לנו, המתכנתים העצלנים, לכתוב קוד שאמור לרוץ ע"י ת'רד אחד בכל פעם. למה מאקרו? כי פיסת הקוד הבאה:

lock (x)
{
  DoSomething();
}

למעשה הופכת להיות הקוד הבא:

System.Object obj = (System.Object)x;
System.Threading.Monitor.Enter(obj);
try
{
  DoSomething();
}
finally
{
  System.Threading.Monitor.Exit(obj);
}

נו, אז? סה"כ עטיפה נוחה ל Monitor.Enter ול Monitor.Exit.

אז בואו נקרא עוד קצת על Monitor.Enter. מתוך MSDN, כל עוד מדובר במערכת Win32, הוא ממופה לפקודה EnterCriticalSection. יופי, בואו נקרא עוד קצת על EnterCriticalSection, שוב מתוך MSDN. נתמקד במשפט אחד:

There is no guarantee about the order in which waiting threads will acquire ownership of the critical section

הממממם. מעניין. אז בואו נסתכל רגע על המצב הבא:

בזמן T0, הת'רד הנוכחי נועל משאב X, ומבצע משימה שלוקחת 5 שניות.

אחרי 2 שניות (נקרא לזה זמן T2), ת'רד נוסף, שנקרא לו מנדל, גם רוצה לנעול את משאב X, ולבצע משימה קטנטונת, שלוקחת 0.01 שניה. מכיוון ש X כבר נעול, מנדל מחכה.

שניה אחרי T2 (נקרא לזה זמן T3), ת'רד נוסף, שנקרא לו צביקי, גם רוצה לנעול את משאב X, ולבצע משימה קטנטונת, שלוקחת 0.01 שניה. שוב, מכיוון ש X כבר נעול, גם צביקי מחכה.

שניה אחרי T3 (נקרא לזה זמן T4), ת'רד נוסף, שנקרא לו פושקש, גם רוצה לנעול את משאב X, ולבצע משימה קטנטונת, שלוקחת 0.01 שניה. ושוב, מכיוון ש X עדיין נעול, גם פושקש מחכה.

עכשיו, סוף סוף עברו 5 שניות מאז T0, ומשאב X משתחרר. יש כרגע שלושה ת'רדים שממתינים ל X: מנדל, צביקי ופושקש. לפי התיעוד למעלה, סדר הביצוע של הת'רדים הוא לא בהכרח סדר ההגעה שלהם. כלומר, זה יכול להיות מנדל-צביקי-פושקש, וזה יכול גם להיות מנדל-פושקש-צביקי, וכל קומבינציה אחרת. בדקתי את העניין, וכתבתי תוכנית קטנה שממחישה את זה. ברוב ההרצות הסדר נשמר. בחלק מההרצות הסדר השתנה. זה מספיק כדי להמחיש שהסדר לא בהכרח נשמר.

בעיה. כי בדיוק רציתי תור, כלומר מבנה נתונים שישמור גם על סדר ההגעה של הת'רדים. מעין message queue.

"ב retlang יש את זה מובנה", אמר לי רשף. בדקתי. retlang זו ספריה בדוט נט שהופכת את התיכנות האסינכרוני להרבה יותר פשוט, מבוסס הודעות, בלי הצורך המעיק בנעילות. כלומר, הספריה הזו עושה בשביל המתכנת את כל הנעילות שהוא צריך. המתכנת, מאידך, צריך ללמוד איך משתמשים בזה. אחרי כמה דוגמאות ומספר נסיונות – זה ממש בסדר. ובאמת יש שם channel שנקרא QueueChannel. הסתכלתי בקוד עצמו. יש שם שימוש ב lock. כלומר, גם שם יש את הבעיה הזו.

כמה מיילים לעולם, ומישהו הציע להסתכל על PLinq, שיש שם מימוש כזה. אבל אני לא יכול להסתכן בספריה כמו Plinq היא עדיין CTP, ועוד לא יצאה לאור באופן רשמי. פעם נכוויתי מספריה לא בשלה (Atlas, למי שזוכר), ומאז כבר למדתי את הלקח.

גוגל! גוגל יעזור לי. רק צריך לבקש, ובעיקר לדעת מה לבקש. אז גיגלתי lock free queue, וחיפשתי גם ב stackoverflow, ומצאתי עולם ומלואו. עולם שלם של אלגוריתמים ומבני נתונים שמיועדים לסביבה שהיא Multi-Threaded ושאין בהם נעילות רגילות, אלא לכל היותר Interlock. אז גיגלתי וריאציות של lock free queue, והנה כמה דברים שמצאתי:

קודם כל, כבר עשו את זה. בכנס שנקרא בקיצור PODC96 ובאריכות Fifteenth ACM Symposium on Principles of Distributed Computing, מתואר מבנה נתונים שמספק את דרישת FIFO, במאמר בעל השם הקצרצר: Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms. כותבי המאמר, מייקל וסקוט, או בקיצור MS, מתארים איך אפשר להשתמש בטכניקות קלות יותר מאשר נעילות (כמו CAS, שבדוט נט זה Interlocked.CompareExchange) כדי לקבל את התוצאה הרצויה. התור (או הרעיון המרכזי שלו) נקרא בהרבה מקומות אחרים MS-Queue. לשם שינוי ה MS מציין את שמות המשפחה מייקל וסקוט, ולא חברת תוכנה ענקית.

יש כבר מימוש לזה בשפות רבות, וגם בדוט נט (C# ליתר דיוק). הבחורצ'יק הזה נותן לנו מימוש מלא.

שני ישראלים, אחד בשם ניר שביט ואחת בשם Edya Ladan Mozes (ואיך מתרגמים את זה לעברית?) מציגים במאמר בשם An Optimistic Approach to Lock-Free FIFO Queues שאפשר לייעל את האלגוריתם המקורי של MS-Queue ולהגיע ל throughput גבוה יותר (בין השאר). מה שנקרא, אנחנו על המפה. אה כן, הנה הלינק לרשימת המאמרים המלאה באתר של ניר שביט.

מה שנקרא, החכמנו.

Edya Ladan Mozes

קטגוריות:כללי תגיות:
Quantcast