Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 3 của 3
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    [SourceCode] Timer(Stopwatch) Multithreaded program C++

    Ngồi mày mò mãi mới được cái này, post lên để ae cùng tham khảo
    Mình cũng là new bie, để cho các bạn đỡ mất công kiếm source code và học lập trình multithreaded nhanh hơn thui [IMG]images/smilies/biggrin.png[/IMG]
    Tài liệu hướng dẫn :
    Multithread - ĐH KHTN

    TIMER
    Mã:
    #include <iostream>
    #include <string>
    #include "conio.h"
    #include "windows.h"
    
    using namespace std;
    
    int minisec = 0;
    int sec = 0;
    int minute = 0;
    int hour = 0;
    
    bool bESCPressed = 0;
    
    DWORD WINAPI CounterThread(LPVOID)
    {
    	while (true)
    	{
    		system("cls");
    		minisec++;
    		if (minisec == 60)
    		{
    			minisec = 0;
    			sec++;
    			if (sec == 60)
    			{
    				sec = 0;
    				minute++;
    				if (minute == 60)
    				{
    					minute = 0;
    					hour++;
    				}
    			}
    		}
    
    		string sHour = (hour > 9) ? to_string(hour) : ("0" + to_string(hour));
    		string sMinute = (minute > 9) ? to_string(minute) : ("0" + to_string(minute));
    		string sSec = (sec > 9) ? to_string(sec) : ("0" + to_string(sec));
    		string sMinisec = (minisec > 9) ? to_string(minisec) : ("0" + to_string(minisec));
    		cout << "************* TIME **************" << endl;
    		cout << "*          " << sHour << ":" << sMinute << ":" << sSec << ":" << sMinisec << "          *" << endl;
    		cout << "*********************************" << endl;
    		Sleep(1);
    
    	}
    	return 0;
    }
    
    DWORD WINAPI OutThreadESC(LPVOID)
    {
    
    	do {
    		bESCPressed = (_getch() == 27);
    	} while (!bESCPressed);
    
    	return 0;
    }
    
    int main()
    {
    	DWORD dwThreadIdCounter;
    	DWORD dwThreadIdOutESC;
    
    	HANDLE hThreadCounter;
    	HANDLE hThreadOutESC;
    
    	hThreadCounter = CreateThread(NULL, 0, CounterThread, NULL, 0, &dwThreadIdCounter);
    	hThreadOutESC = CreateThread(NULL, 0, OutThreadESC, NULL, 0, &dwThreadIdOutESC);
    
    	while (!bESCPressed);	// Chuong trinh dung lai de cho: neu khong thread chinh tat thi cac thread con cung tat theo
    
    	return 0;
    }
    CodePad : http://codepad.org/OC7zdemM

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Chương trình của bạn có một số chỗ chưa hợp lý như sau:

    1.Sử dụng biến toàn cục mà không có locking hay mutex: Khi dùng thread để xử lý , các biến toàn cục khi được tham chiếu đều phải lock, tránh đụng độ. Do các biến như int, bool có tính nguyên tố, nên trong trường hợp này có thể tạm coi là chấp nhận được.

    2.Không dừng thread đúng cách: 1 thread dừng lại khi bản thân nó thoát khỏi vòng lặp xử lý, không phụ thuộc vào thread khác. Giả sử thread đang mở các tài nguyên như mở file, ghi file, hoặc kết nối mạng, nếu dừng thread không đúng cách sẽ phát sinh lỗi.

    3.Không CloseHandle đối với các handle mới tạo ra, gây ra leak handle. Tuy là ví dụ nhưng mình nghĩ nên viết chuẩn, để người khác đọc không bị thiếu sót.

    4. Main thread sử dụng lệnh sau để đợi các thread khác hoạt động xong:

    Mã:
    while (!bESCPressed);   // Chuong trinh dung lai de cho: neu khong thread chinh tat thi cac thread con cung tat theo
    cách này được gọi là busy polling. Cách này thường gây lãng phí tài nguyên của máy tính, được khuyến cáo là không nên dùng.


    Mình viết 1 ứng dụng nhỏ để làm rõ hơn các ý mình vừa nói. Đây là code của mình:
    Trước khi tạo thread, mình tạo một Event, đặt tên là stopEvent.
    Mục đích của Event này là báo cho thread Counter biết khi nào cần dừng lại.
    Khi nhấn ESC, OutThreadESC sẽ thiết lập event này, để CounterThread biết và stop đúng cách.

    Main thread sẽ đợi khi cả 2 thread dừng lại mới kết thúc, thông qua hàm WaitForMultipleObjects

    Mã:
    #include <stdio.h>#include <conio.h>#include <Windows.h> enum{    CounterThreadIndex = 0,    OutThreadESCIndex = 1}; DWORD WINAPI CounterThread (__in_opt LPVOID lpParam){    SYSTEMTIME sysTime = {};    int printedChar = 0;     if (lpParam == NULL)        return 0;     HANDLE hStopEvent = *(HANDLE*)lpParam;     printf("Current time: ");    while( WaitForSingleObject(hStopEvent, 0) == WAIT_TIMEOUT) // check stop-event    {        // get current time        GetSystemTime(&sysTime);        GetLocalTime(&sysTime);        // print current time        printedChar = printf(            "%02d/%02d/%04d %02d:%02d:%02d",             sysTime.wDay, sysTime.wMonth, sysTime.wYear,             sysTime.wHour, sysTime.wMinute, sysTime.wSecond            );          // sleep 1 second        Sleep(1000);        // clear screen        for (int i = 0; i < printedChar; ++i)            printf("\b");    }    delete (HANDLE*)lpParam;    return 0;} DWORD WINAPI OutThreadESC (__in_opt LPVOID lpParam){    BOOL bESCPressed  = FALSE;     // check parameter    if (lpParam == NULL)        return 0;     // get stop event handle    HANDLE hStopEvent = *(HANDLE*)lpParam;     // wait for ESC    do {        bESCPressed = (_getch() == 27);    } while (!bESCPressed);     // set stop-event    SetEvent(hStopEvent);    printf("
    
    Stopping counter thread...
    ");    delete (HANDLE*)lpParam;    return 0;} int main(int argc, char **argv){    HANDLE hStopEvent = NULL;    HANDLE hThread[2];      hStopEvent = CreateEvent(        NULL, // security attrib        TRUE, //manual reset        FALSE, // Initial state        NULL // No-name        );     // error    if (hStopEvent == NULL)        return 1;     hThread[CounterThreadIndex] = CreateThread(        NULL, // thread attrib        0, // stack size        CounterThread, //        new HANDLE(hStopEvent), // stop event handle cloned        0, // creation flag        NULL // pointer to thread id        );    if (hThread[CounterThreadIndex] == NULL)// failed    {        CloseHandle(hStopEvent); // release event        return 1;    }     hThread[OutThreadESCIndex] = CreateThread(        NULL, // thread attrib        0, // stack size        OutThreadESC, //        new HANDLE(hStopEvent), // stop event handle cloned        0, // creation flag        NULL // pointer to thread id        );     if (hThread[OutThreadESCIndex] == NULL)// failed    {        SetEvent(hStopEvent);// stop thread         if (WAIT_TIMEOUT == WaitForSingleObject(hThread[CounterThreadIndex], 5000))// wait            TerminateThread(hThread[CounterThreadIndex], 0);         // release event        CloseHandle(hThread[CounterThreadIndex]);        CloseHandle(hStopEvent);        return 1;    }     // wait all threads    WaitForMultipleObjects(2, hThread, TRUE, INFINITE);     // close all Handles    for (unsigned int i = 0; i < 2; ++i)        CloseHandle(hThread[i]);        CloseHandle(hStopEvent);     printf("
    
    Stopped!
    ");    getch();    return 0;}

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Cảm ơn bạn đã góp ý, tks so much !

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •