الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.
Tutorial

Multithread

مغلق
بدأه glimps في 6 ديسمبر 2005 · 17 رد · 2,041 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

بصراحة لا اعلم افضل طريقة للشرح في منتدى به الاف من الاعضاء
اكتب الكود و اعلق ام ماذا ...

ليتكم تساعدوني بالاسئلة - داخل اطار البرنامج -

الـMutlithread امر مهم جدا احيانا يكون الكمبيوتر مشغول بالقراءة من الكيبورد او التعامل مع الشاشة
او كارت الشبكات فبدلا من تنفيذ البرنامج بطريقة تسلسلية من الممكن ان تصممه بالعمل كعدة اجزاء
thread يعني خيط !!! المهم البرنامج يكون بعدة انفاس او ارواح من الممكن ان تنفذ بدون تسلسلية

البرنامج ليس مثالي و كتب بعرض تعليمي و من الممكن اجراء الكثير من التعديلات!!!
همي الاول السهولة و البساطة اليكم
الكود و ندير حلقة نقاشية تعليمية حوله ما رأيكم دام فضلكم - يا ترى الشاى على مين

 

// dos2.cpp : A good example of MultiThread Program with emphasis of pointer.////#include "stdafx.h"//#include <stdlib.h>#include <stdio.h>#include <process.h>#define ddum(a,b) a+bint addem(int);int factoria(int);int AddThree(int list[]);int DataAdd(int *list);int StrPrint(char *str);int side=4;int main(int argc, char* argv[]){// int arr[2];arr[1]=4;arr[2]=5;// float *ptr_y,yy[2]={3.0,9.2};int id1,id2,id3,id4,id5;int list[]={3,5,19},kll[]={8,1,2,3,4,5,6,7};int (*ptr)(char *str);char str[] = "*** Pointing to a function.";ptr = StrPrint;printf(" --** Hello World! **--\n");id1=_beginthread((void (*)(void *))addem, 0, (void *)4);id2=_beginthread((void (*)(void *))factoria, 0, (void *)4);id3=_beginthread((void (*)(void *))AddThree, 0, (void *) list);id4=_beginthread((void (*)(void *))DataAdd, 0, (void *) kll);id5=_beginthread((void (*)(void *))ptr, 0, (void *) str);addem(20);(*ptr)(str);if ((*ptr)(str)) printf("Done!\n");/* printf("Sum of %d and %d is %d",arr[1],arr[2],ddum(arr[1],arr[2]));printf("\npid1 = %d, pid2 = %d, pid3 = %d\n\n",id1,id2,id3);ptr_y = &yy[0];printf("ptr_y: address=0x%p, content=0x%p\n", &ptr_y, ptr_y);printf("*ptr_y +7 => %5.2f.......*(ptr_y + 1) => %5.2f\n", *ptr_y +7,*(ptr_y+1));printf("%f ..... %f\n\n",yy[0],yy[1]);AddThree(list);DataAdd(kll);*/ return 0;}int addem(int count){int i, sum;sum = 0;for (i=0; i<=count; ++i) {printf("I The value of I is %d\n", i);fflush(stdout);sum += i;}printf("I *** The sum is %d\n", sum);fflush(stdout);return 0;}int factoria(int don){int j, mul;mul=1;for(j=1;j<=don;j++) {printf("II The value of II is %d\n", j);fflush(stdout);mul *= j;}printf("II *** The mul is %d\n", mul);fflush(stdout);return 0;}int AddThree(int list[]){int i;int result =0;for (i=0; i<3; i++){printf("III The Value of III is %d\n",i);result += list;}printf("III *** The sum of the three integers is: %d\n", result);return 0;}int DataAdd(int *listt){int i;int sum =0,max=listt[0];// printf("max is %d\n",max);for (i=1; i<max; i++){printf("IVV The Value of IVV is %d\n",i);sum += listt;}printf("IVV *** The Sum is %d\n",sum);return 0;}int StrPrint(char *str){printf("%s\n", str);return 1;}

الـOutput و بالطبع يختلف من جهاز بل على نفس الجهاز يختلف من ظرف لاخر

C'est la Multithread
 

--** Hello World! **--
I The value of I is 0
I The value of I is 0
II The value of II is 1
III The Value of III is 0
IVV The Value of IVV is 1
*** Pointing to a function.
IVV The Value of IVV is 2
IVV The Value of IVV is 3
IVV The Value of IVV is 4
IVV The Value of IVV is 5
IVV The Value of IVV is 6
IVV The Value of IVV is 7
IVV *** The Sum is 28
III The Value of III is 1
I The value of I is 1
I The value of I is 2
I The value of I is 3
I The value of I is 4
I The value of I is 5
I The value of I is 6
I The value of I is 7
I The value of I is 8
I The value of I is 1
II The value of II is 2
III The Value of III is 2
III *** The sum of the three integers is: 27
II The value of II is 3
II The value of II is 4
II *** The mul is 24
I The value of I is 2
I The value of I is 3
I The value of I is 4
I *** The sum is 10
I The value of I is 9
I The value of I is 10
I The value of I is 11
I The value of I is 12
I The value of I is 13
I The value of I is 14
I The value of I is 15
I The value of I is 16
I The value of I is 17
I The value of I is 18
I The value of I is 19
I The value of I is 20
I *** The sum is 210
*** Pointing to a function.
*** Pointing to a function.
Done!

و الان اتركه لكم ثم نرجع له لما يشاء المناقشة

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 18 أبريل 2014 في 17:33 — السبب: add some tags

1
#2

لمن يريد مناقشة الموضوع بالاسمبلي عليه بالرابط

/index.php?showtopic=82693

#3

السلام عليكم ورحمة الله وبركاته

شكرا لك أخ glimps على المثال

طبعاً عندي استفسارات :D , يمكن تبعد بعض الشيء عن الهدف الأساسي لكنها ستفيد إن شاء الله

1 - لماذا استخدام دوال السي / سي++ القياسية , لماذا لم تستخدم الـ API الخاصه بنظام التشغيل ؟

2 - هل ربط البرنامج بدوال السي / سي++ القياسيه سيكون static أم dynamic , أعتقد انه static

3 - خاص بتحويل الكود الى أسمبلي , المشكله مره اخرى عند عملية الربط مع الدوال القياسية , المكتبات المستخدمه غير متضمنة في كود الأسمبلي

4 - fflush لماذا , هل لها داعي ؟ ما الكارثه في تركها

وامهلني بعض الوقت حتى أرى قصة _beginthread لأني أول مره اعرفها كنت استخدم CreateThread في ويندوز وما جربت على غيره

#4

و عليكم السلام و رحمة الله و بركاته

اخي الفاضل البرنامج تعليمي فالغرض منه التعلم اولا و اخيرا .. اما انت اخي الفاضل فالواضح انك تكتب برامج

اما غرضي من البرنامج فهو لمن لم يكتب مثل هذه البرامج حتي يتجرئ و يستعمل خواص الـmultithreading

و الـpointers حتي ينطلق بعد ذلك لامور اخري و البرنامج لقرائته يحتاج لاساسيات السي فقط.

اما حكاية الربط مع المكتبات . فما اريده ان يقوم الاخ بمحاولة الcompilation بنفسه لديه compiler Visual Studio 6,7,8 اذا لديه

هذه المكتبات اذا لا توجد مشكلة هنا او في الاسمبلي INCLUDELIB .

البرنامج ليس للقراءة بل للتجربة العملية و الا التعلم كان قراءة فقط بدون ممارسة

ثم عادة مكتبات السي اقل تغير من خواص النظام.

و الـfflush مفيدة.

رجاء جربوا البرنامج . عن نفسي احب ان ارى شكل الـoutput من اجهزة مختلفة.

#5

معلش :D , انا جربت الكود أول ما شوفته وادي كمان مره , الخرج بتاعه

 --** Hello World! **--
I The value of I is 0
I The value of I is 1
I The value of I is 2
I The value of I is 3
I The value of I is 0
I The value of I is 4
I The value of I is 1
I *** The sum is 10
I The value of I is 2
I The value of I is 3
III The Value of III is 0
I The value of I is 4
III The Value of III is 1
III The Value of III is 2
I The value of I is 5
III *** The sum of the three integers is: 27
I The value of I is 6
*** Pointing to a function.
II The value of II is 1
I The value of I is 7
II The value of II is 2
I The value of I is 8
II The value of II is 3
I The value of I is 9
II The value of II is 4
I The value of I is 10
I The value of I is 11
II *** The mul is 24
I The value of I is 12
I The value of I is 13
IVV The Value of IVV is 1
I The value of I is 14
IVV The Value of IVV is 2
IVV The Value of IVV is 3
I The value of I is 15
IVV The Value of IVV is 4
IVV The Value of IVV is 5
I The value of I is 16
IVV The Value of IVV is 6
IVV The Value of IVV is 7
I The value of I is 17
IVV *** The Sum is 28
I The value of I is 18
I The value of I is 19
I The value of I is 20
I *** The sum is 210
*** Pointing to a function.
*** Pointing to a function.
Done!
#6

السلام عليكم

الخطر الذى يهدد برنامجك هو ان البرنامج قد ينتهى ويغلق جميع الـThreads التى تعمل فى الخلفية قبل ان يحصل على إشارة من الـThreads لذلك انصحل بإستخدام الدالة

WaitForMultipleObjects حتى تتاكد انك حصلت على النتيجة من كل thread قبل ان تنهى برنامجك.

والسلام عليكم

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#7

بسم الله الرحمن الرحيم

اخي Asm4all

بارك الله فيك لا يفضل ابدا استعمال api call مع c/c++ standard Library لانها دوما تؤدي

الي memory leak الخلط بينهم مؤذي ok

_beginthread or _beginthreadex

افيد في هذه الحالة و لامور اخرى... حبة حبة بنقول بسم الله

أستاذ أحمد ليتك توضح متي يحدث هذا الخطر بالضبط برمجيا حتي نتناقش و تعم الفائدة و ان كان

هذا الامر خارج عن الاطار الاساسي و الحمد لله على كل حال.

يا سلام يا ما نفسي ارى من يجرب و يقول البرنامج لا يعمل

كيف يتم الـcompilation

cl multi.c

ام ماذا ؟؟؟؟؟؟

تم تعديل هذه المشاركة بواسطة glimps في 7 ديسمبر 2005 في 07:25

#8

بسم الله الرحمن الرحيم

سوف اترك هذا الموضوع اسبوع اسبوعين ثم نرى ان كان له زبائن

ممكن نتطرق لامور متقدمة

Priority

Synchronization

Mutex

Semaphore

The Macho way

MFC UI Thread

و غيرها ...........

طبعا الامر متوقف على الاستجابة ... فما اضيق الاوقات و لاداعي

ان اضايقكم بما لا تريدون مفروض في الضيف ان يكون خفيف

موضوع ليس له زبائن لا داعي لاكماله

بعد اذنكم اروح اكتب compiler عند جماعة السي شارب

تم تعديل هذه المشاركة بواسطة glimps في 7 ديسمبر 2005 في 13:34

#9

بسم الله الرحمن الرحيم

بالنسبة للسؤال حول الـmemory leak

يعني تسريب بالذاكرة طبعا هنا الامر هين لكن من الافضل الابتعاد عنها بالاخص

لمن يريد برمجة نظم او درايفر

و الافضل دوما تفاديها قدر الامكان اقل اضرارها ضياع موارد بدون لزمة و ان زادت على الحد

تؤدي الى اضطراب النظام و التهينجات و الخ

فالـgarbage collection - في الدوت نت او الجافا - لم تستخدم الا لتفادي مثل هذه العادات

الخلط بين الwindows api و الـ standard c/c++ library يؤدي الي هذا الامر

يعني اما تتعود على استعمال windows api فقط او c/c++ library فقط

اتمنى ان تكون وضحت الصورة.

#10

جمييل انك جيبت سيرة الذاكرة , أصلي القيت نظرة سريعه في MSDN فوجدت مثال بالـ API وقمت بتغير اسطر بسيطة فيه ليكون سهل على مبرمج السي++ الطبيعي :D , يعني يستخدم new و delete بدل دوال الـ API للتعامل مع الهيب

عموما المثال هكذا

#include <windows.h>
#include <stdio.h>

#define MAX_THREADS 3

typedef struct _MyData {
  int val1;
  int val2;
} MYDATA, *PMYDATA;
DWORD WINAPI ThreadProc(LPVOID lpParam ) { 
  PMYDATA pData;
  // Cast the parameter to the correct data type.
  pData = (PMYDATA)lpParam;
  // Print the parameter values.
  for(int i = 0; i < 5; i++) {
    printf("
 Thread_%d Send %d\n",pData->val1, pData->val2+i);
  }
  // Free the memory allocated by the caller for the thread data structure.
  delete pData;
  return 0;
}
void main() {
  PMYDATA pData;
  DWORD dwThreadId[MAX_THREADS];
  HANDLE hThread[MAX_THREADS];
  // Create MAX_THREADS worker threads.
  for(int i = 0; i < MAX_THREADS; i++) {
    // Allocate memory for thread data.
    if((pData = new MYDATA) == NULL)
      ExitProcess(2);
    // Generate unique data for each thread.
    pData->val1 = i;
    pData->val2 = 100 * i + 100;
    if((hThread = CreateThread( 
        NULL,              // default security attributes
        0,                 // use default stack size  
        ThreadProc,        // thread function 
        pData,             // argument to thread function 
        0,                 // use default creation flags 
        &dwThreadId)   // returns the thread identifier 
        ) == INVALID_HANDLE_VALUE) // Check the return value for success.
      ExitProcess(i);
  }
  // Wait until all threads have terminated.
  WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); // VI
  // Close all thread handles upon completion.
  for(int i = 0; i < MAX_THREADS; i++)
    CloseHandle(hThread);
}

المثال الأصلي

لاحظ استخدام الدالة التي تحدث عنها احمد WaitForMultipleObjects , لاحظ ايضا أن دالة الثريد تقوم بتحرير الذاكرة التي استخدمها البرنامج لارسال بيانات الى الدالة

#11

كما هو واضح من مثال الاخ "عاصم" :lol: البرنامج سيقوم بالانظار حتى تنتهى جميع الThreads من عملها قبل إنهاء البرنامج...

فى بعض الاحيان قد نحتاج الحصول على نتيجة حتى يتسنى لنا المواصلة وربما تكون هذه النتيجه هى return نحصل عليه من Thread معين فى هذه الحاله علينا ان نستخدم الدالة WaitForSingleObject وهى التى تعطينا الضوء الاخضر على ان الThread قد انهى عمله...

والسلام عليكم

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#12

عادة ما احتقر الـmsdn!!!!

عاصم

انظر داخل

windows 2000 Advanced APi& System Programming

Black Book Al Williams

او

Windows NT4/2000 Programming

from the ground Up

H. Shildt

افضل

احمد غريب بصراحة في موضوع ما رأيت لك كلمة

العلم لا يكيل الا الباذنجان

اهانة كبيرة للعلم و كل ما يخصه و تمجيد للجهل

كلمة سيئة جدا لو خلطت بماء البحر لعكرته فلا اجد في نفسي اي رغبة

للرد عليك

انا لم انفي و لم اؤكد لكني لا اود الرد عليك او التعليق على مواضيعك

تم تعديل هذه المشاركة بواسطة glimps في 8 ديسمبر 2005 في 04:04

#13

الكتب تجدها بدار المعارف او الاهرام او المكتبة الاكاديمية

#14
اقتباس
عادة ما احتقر الـmsdn!!!!
رأيك , انت حر فيه , عن نفسي اعتبرها المرجع رقم واحد في الـ API وبعدها windows NT-2000-XP undocumented API , وللأمثلة codeproject وجووجل عموما
اقتباس
عاصم
:(

يا جماعه , خلاص انا حاعترف , انا عاصم , مش احمد استريحتم :( :s , استريحت يا عم احمد :angry: , استريحت يا glimps :angry: , استريحت يا اياس :angry: :angry: :angry: منك لله يا اياس انت السبب :s

بالنسبه للكتب سوف ابحث عنها واتمنى ان تكون أفضل من MSDN التي تحتقرها :rolleyes:

اما موضوع الاهانة وغيره فلا تتسرع في الحكم , و فرق بين الضحك والجد

أخوكم , عاصم ( أحمد سابقا )

#15

سيبك من التهريج و اعوذ بالله من الكذب ...احب الصراحة

و اقسم بالله لا احل اي شخص يتكلم عني بكلمة في غيبتي

و الله الموعد

تم تعديل هذه المشاركة بواسطة glimps في 8 ديسمبر 2005 في 05:33

#16
glimps كتب:
سيبك من التهريج و اعوذ بالله من الكذب ...احب الصراحة

و اقسم بالله لا احل اي شخص يتكلم عني بكلمة في غيبتي

و الله الموعد

:blink: نعم ؟

هو ده الموضوع اللي كنت عايز تكتب فيه الرد ده ؟ ولا جات غلط؟؟؟ لو غلط قوللي وانا بامسحها أو انقلهالك في مكانها

لو صح , وضح الهدف من هذا الرد باختصار

#17

هو إيه إلى حصل بالظبط؟؟

انا مش فاهم اى حاجة..

ممكن توضح إيه إلي مضايقك, لانى لا ارى احد اهانك او تعرض لك, على الاقل فى هذا الموضوع...

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#18

-09

الاستاذ //

glimps

اشكرك على هذا الموضوع الجميل جدا وانا في بداية تعلمي له

استاذي الكريم

ان الكود الذي انت كتبته لم يعمل عندي فهناك خطأ واحد كالتالي:

Function 'beginthread' should have a prototype

كما ان هناك كثير من المتغيرات غير مستخدمة ابدا (Compailer على كلام الـ )

فقمت بمسح السطر الذي يوجد به الخطأ و جميع الاسطر التي غير مستخدمة والنتيجة ان البرنامج قد عمل

انا الى الان لم اقم بتتبع البرنامج ولم افهمه جيدا ولكن اود قبل ذلك معرفة

تفسير ذاك الخطأ والمتغيرات الغير مستخدمة ولك مني جزيل الشكر :rolleyes:

هذا الموضوع مغلق.

مواضيع مشابهة