日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程学习(一)----CreateThread

發(fā)布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程学习(一)----CreateThread 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
// tt.cpp : 定義控制臺應用程序的入口點。

//同一進程中的多個線程將共享該進程中的全部系統(tǒng)資源,如虛擬地址空間、文件描述符和信號處理等,但是同一個進程中的多個線程都有各自的調用棧、寄存器環(huán)境和線程本地存儲。

//線程都擁有自己的堆棧,臨界區(qū)等主要是控制訪問全局變量和成員變量


#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <conio.h>

#define WM_NIHAO? 1001
#define THREADNUM 3

/*
volatile 修飾符的作用是告訴編譯器無需對該變量作任何的優(yōu)化,即無需將它放到一個寄存器中,并且該值可被外部改變。
對于多線程引用的全局變量來說,volatile 是一個非常重要的修飾符。
*/
volatile int??????????? gInt=0;
//普通臨界區(qū)
static CRITICAL_SECTION cs;
//MFC臨界區(qū)
//CCriticalSection??????? ccs;

//使用原子操作的方法
volatile LONG aomic=100;

void fun(int tNum)
{
?? ?//printf("第%d線程已經工作了\n",tNum);

?? ?if (1)
?? ?{
?? ??? ?//臨界區(qū)
?? ??? ?EnterCriticalSection(&cs);// 進入臨界區(qū),其它線程則無法進入
?? ??? ?//ccs.Lock();
?? ??? ?// 安全訪問該區(qū)域 ?
?? ??? ?gInt--;
?? ??? ?printf("第%d線程檢測到全局變量gInt的值是:%d\n",tNum,gInt);
?? ??? ?Sleep(0);//致使不使用臨界區(qū)肯定出錯的方法
?? ??? ?gInt++;
?? ??? ?printf("第%d線程檢測到全局變量gInt的值是:%d\n",tNum,gInt);
?? ??? ?//ccs.Unlock();
?? ??? ?LeaveCriticalSection(&cs);? // 離開臨界區(qū),其它線程可以進入

?? ??? ?//原子操作
?? ??? ?InterlockedIncrement(&aomic);
?? ??? ?InterlockedDecrement(&aomic);
?? ?}

?? ?MSG?? msg;? ?
?? ?//GetMessage 是 從調用線程的消息隊列里取得一個消息并將其放于指定的結構。
?? ?//GetMessage不接收屬于其他線程或應用程序的消息。獲取消息成功后,線程將從消息隊列中刪除該消息。函數會一直等待直到有消息到來才有返回值。
?? ?//返回值:如果函數取得WM_QUIT之外的其他消息,返回非零值。如果函數取得WM_QUIT消息,返回值是零。如果出現了錯誤,返回值是-1。
?? ?while(1)
?? ?{? ?
?? ??? ?int tGM=::GetMessage(&msg,NULL,0,0);
?? ??? ?switch(msg.message)? ?
?? ??? ?{? ?
?? ??? ?case WM_NIHAO:? ?
?? ??? ??? ?printf("第%d線程接收到主線程的發(fā)過來的消息:%s\n",tNum,(char*)msg.wParam);
?? ??? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?break;
?? ??? ?}

?? ??? ?//不需要接收第二次消息
?? ??? ?if (tGM>0)
?? ??? ?{
?? ??? ??? ?break;
?? ??? ?}
?? ?}

?? ?printf("%d線程結束",tNum);

?? ?//該函數用于線程終結自身的執(zhí)行,主要在線程的執(zhí)行函數中被調用。其中參數dwExitCode用來設置線程的退出碼。
?? ?//ExitThread(1);
}
int _tmain(int argc, _TCHAR* argv[])
{
?? ?// 在進入多線程環(huán)境之前,初始化臨界區(qū) ?
?? ?InitializeCriticalSection(&cs); ?

?? ?DWORD threadId[THREADNUM];
?? ?HANDLE hThread[THREADNUM];
?? ?for (int i=0;i<THREADNUM;i++)
?? ?{
?? ??? ?hThread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)fun,(LPVOID)i,CREATE_SUSPENDED,&(threadId[i]));
?? ?}

?? ?while (getch()!='1')
?? ?{
?? ??? ?Sleep(100);
?? ?}
?? ?//試探線程讀取全局變量
?? ?gInt=100;
?? ?for (int i=0;i<THREADNUM;i++)
?? ?{
?? ??? ?if (-1==ResumeThread(hThread[i]))
?? ??? ?{
?? ??? ??? ?printf("ResumeThread時候出錯了\n");
?? ??? ??? ?return -1;
?? ??? ?}
?? ??? ?
?? ?}
?? ?//ResumeThread線程之后線程投入工作需要一定時間
?? ?Sleep(1000);

?? ?char buff[20]="ni hao ma?";
?? ?for (int i=0;i<THREADNUM;i++)
?? ?{
?? ??? ?BOOL bPostMes=PostThreadMessage(threadId[i],WM_NIHAO,(WPARAM)buff,(LPARAM)strlen(buff));
?? ?}
?? ?//參數一:線程句柄
?? ?//參數二:等待時間(毫秒),IGNORE:不等,INFINITE:死等
?? ?//返回值: WAIT_OBJECT_0: 線程結束
?? ?//?? ??? ??? WAIT_TIMEOUT:超過等待時間,指定的對象處于無信號狀態(tài)
?? ?//?? ??? ??? WAIT_ABANDONED:WAIT_ABANDONED_0至(WAIT_ABANDONED_0 + nCount - 1)如果bWaitAll為TRUE,則返回值表明所有指定對象的狀態(tài)是觸發(fā)的,并且至少對象之一,是一個廢棄的互斥對象。

?? ?//???????? WAIT_FAILED:出現錯誤,一般是線程句柄錯誤

??? //WaitForSingleObject函數,此函數的作用是監(jiān)視hHandle的狀態(tài),當監(jiān)視的句柄為有信號狀態(tài)時,即此對象為空閑狀態(tài)時,此函數返回,才能執(zhí)行其后的代碼。

?? ?//WaitForSingleObject(hThread,INFINITE);

?? ?Sleep(1000);
?? ?//值得注意的是hThread數組的所有成員必須全部有效,有一個沒效的話,次函數就會執(zhí)行失敗
?? ?DWORD wm=WaitForMultipleObjects(THREADNUM,hThread,true,10000);
?? ?//若果第三個參數是true,則返回值代表所有線程的狀態(tài)
?? ?//若果第三個參數是false,則返回值代表那個有返回線程的狀態(tài)
?? ?switch (wm)
?? ?{
?? ?case WAIT_FAILED:
?? ??? ?printf("wm-->WAIT_FAILED\n");
?? ??? ?break;
?? ?case WAIT_TIMEOUT:
?? ??? ?printf("wm-->WAIT_TIMEOUT\n");
?? ??? ?break;

?? ?case WAIT_ABANDONED_0+0:
?? ?case WAIT_ABANDONED_0+1:
?? ?case WAIT_ABANDONED_0+2:
?? ??? ?printf("wm-->WAIT_ABANDONED_0\n");
?? ??? ?break;

?? ?case WAIT_OBJECT_0+0:
?? ?case WAIT_OBJECT_0+1:
?? ?case WAIT_OBJECT_0+2:
?? ??? ?printf("wm-->WAIT_OBJECT_0\n");
?? ??? ?break;

?? ?default:
?? ??? ?break;
?? ?}

?? ?//一般情況下,線程運行結束之后,線程函數正常返回,但是應用程序可以調用TerminateThread強行終止某一線程的執(zhí)行。
?? ?for (int i=0;i<THREADNUM;i++)
?? ?{
?? ??? ?TerminateThread(hThread[i],0);
?? ?}

?? ?// 釋放臨界區(qū)資源,當不再使用臨界區(qū)時調用該函數 ?
?? ?DeleteCriticalSection(&cs); ?
?? ?return 0;
}

總結

以上是生活随笔為你收集整理的多线程学习(一)----CreateThread的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。