C语言多线程编程一
1. Windows下同時打開多個對話框:
#include <Windows.h> #include <process.h> //創(chuàng)建線程void runmsg(void *p) {MessageBoxA(0, "hello world", "hello china", 0);}void main() {_beginthread(runmsg, 0, NULL); //啟動線程,函數(shù)地址,把函數(shù)當做線程的入口點_beginthread(runmsg, 0, NULL);_beginthread(runmsg, 0, NULL);_beginthread(runmsg, 0, NULL);system("pause"); }?2. 多線程實現(xiàn)同步和異步:
#include <Windows.h> #include <stdlib.h>//typedef unsigned long DWORD; //#define WINAPI __stdcall 標準的呼叫 //typedef void far *LPVOID; DWORD WINAPI MyMseg(LPVOID lp) {MessageBoxA(0, "hello", "china", 0); }void main() {HANDLE hthread;DWORD threadid; //保存線程編號//異步執(zhí)行://for (int i = 0; i < 5; i++)//{// hthread = CreateThread(// NULL, //安全屬性// NULL, //堆棧大小// MyMseg, //線程的入口點// NULL, //函數(shù)的參數(shù)// 0, //立刻執(zhí)行// &threadid //保存線程的id// );//}//多線程實現(xiàn)同步: for (int i = 0; i < 5; i++){hthread = CreateThread(NULL, //安全屬性NULL, //堆棧大小MyMseg, //線程的入口點NULL, //函數(shù)的參數(shù)0, //立刻執(zhí)行&threadid //保存線程的id );WaitForSingleObject(hthread, INFINITE); //等待CloseHandle(hthread); //關閉線程 }system("pause"); } #include <stdio.h> #include <stdlib.h> #include <process.h> #include <Windows.h>void run(void *p) {int *px = p;printf("線程編號%d\n", *px); }void main() {int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };for (int i = 0; i < 10; i++){HANDLE hd = (HANDLE) _beginthread(run, 0, &a[i]); //MyThread線程編號WaitForSingleObject(hd, INFINITE); //單線程//WaitForMultipleObjects() //多線程 }system("pause"); }
3. 多線程檢索:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> //生成隨機數(shù) #include <process.h>int isfind = 0; //找到設置為1,其他線程就不再查找struct findInfo {int *pstart; //線程檢索的首地址int length; //檢索的數(shù)據(jù)長度int findNum; //需要查找的數(shù)據(jù) int id; //線程的編號 };void findIt(void *p) {struct findInfo *ps = p; //保存地址printf("\n線程%d開始查找\n", ps->id);//遍歷首地址,長度為10個元素for (int *pf = ps->pstart; pf < ps->pstart + ps->length; pf++){if (isfind == 1){printf("線程%d結束查找,其他線程已經(jīng)找到\n", ps->id);return;}if (*pf == ps->findNum){printf("線程%d結束查找,找到數(shù)據(jù)%d地址%p\n", ps->id, *pf, pf);isfind = 1;return;}}printf("線程%d結束查找\n", ps->id);}void main() {int a[100] = { 0 };time_t ts;unsigned int data = time(&ts);srand(data); //隨機數(shù)種子for (int i = 0; i < 100; i++){a[i] = rand() % 100;printf("%4d", a[i]);if ((i+1) % 10 == 0) //每10個打印一行 {printf("\n");}}int num;printf("輸入要查詢的數(shù):\n");scanf("%d", &num);struct findInfo info[10]; //結構體數(shù)組,保存每個線程要查找的信息for (int i = 0; i < 10;i++){info[i].pstart = a + 10 * i;info[i].length = 10;info[i].findNum = num;info[i].id = i;_beginthread(findIt, 0, &info[i]); //調(diào)用線程 }system("pause"); }?4. 多線程切割:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <time.h> //生成隨機數(shù) #include <process.h>int isfind = 0; //找到設置為1,其他線程就不再查找struct findInfo {int *pstart; //線程檢索的首地址int length; //檢索的數(shù)據(jù)長度int findNum; //需要查找的數(shù)據(jù) int id; //線程的編號 };#define M 100 //數(shù)據(jù) #define N 8 //線程數(shù)量void findIt(void *p) {struct findInfo *ps = p; //保存地址printf("\n線程%d開始查找\n", ps->id);//遍歷首地址,長度為10個元素for (int *pf = ps->pstart; pf < ps->pstart + ps->length; pf++){if (isfind == 1){printf("線程%d結束查找,其他線程已經(jīng)找到\n", ps->id);return;}if (*pf == ps->findNum){printf("線程%d結束查找,找到數(shù)據(jù)%d地址%p\n", ps->id, *pf, pf);isfind = 1;return;}}printf("線程%d結束查找\n", ps->id); }void main() {int a[100] = { 0 };time_t ts;unsigned int data = time(&ts);srand(data); //隨機數(shù)種子for (int i = 0; i < 100; i++){a[i] = rand() % 100;printf("%4d", a[i]);if ((i+1) % 10 == 0) //每10個打印一行 {printf("\n");}}int num;printf("輸入要查詢的數(shù):\n");scanf("%d", &num);struct findInfo info[N]; //結構體數(shù)組,保存每個線程要查找的信息if (M%N == 0) //前面能整除的情況 {for (int i = 0; i < N; i++){info[i].pstart = a + M/N * i;info[i].length = M/N;info[i].findNum = num;info[i].id = i;HANDLE hd = _beginthread(findIt, 0, &info[i]);}}else //不能整除的情況 {for (int i = 0; i < N-1; i++){info[i].pstart = a + M / (N-1) * i;info[i].length = M / (N - 1);info[i].findNum = num;info[i].id = i;HANDLE hd = _beginthread(findIt, 0, &info[i]);}//info[N-1];int i = N - 1;info[i].pstart = a + M / (N - 1) * i;info[i].length = M % (N - 1);info[i].findNum = num;info[i].id = i;HANDLE hd = _beginthread(findIt, 0, &info[i]);}system("pause"); }?5. 多線程沖突:
#include <stdio.h> #include <stdlib.h> #include <process.h> #include <Windows.h> #include <time.h>CRITICAL_SECTION cs; //臨界區(qū),全局int num = 0; //全局變量,多線程同時訪問會發(fā)生沖突//10 * 100 * 100 DWORD WINAPI myfun(void *p) {for (int i = 0; i < 100; i++){EnterCriticalSection(&cs); //進入臨界區(qū)num++;LeaveCriticalSection(&cs); //離開臨界區(qū)//Sleep(10); }return 0; }void main() {time_t start, end;time(&start);HANDLE hd[100];for (int i = 0; i < 100; i++){hd[i] = CreateThread(NULL, 0, myfun, NULL, 0, NULL);//hd[i] = _beginthread(myfun, 0, NULL); //線程數(shù)組,數(shù)組的每一個元素都是一個線程//WaitForSingleObject(hd[i], INFINITE); //等待單個的線程結束(同步) }WaitForMultipleObjects(100, hd, TRUE, INFINITE); //等待所有線程退出 time(&end);printf("%f\n", difftime(end, start));printf("%d\n", num);DeleteCriticalSection(&cs);system("pause"); }6. 多線程的操作:
#include <stdio.h> #include <stdlib.h> #include <process.h> #include <Windows.h>//_beginthread CreateThread 創(chuàng)建線程 //_endthread ExitThread 內(nèi)部結束線程 TerminateThread 外部強制結束 //SuspendThread凍結 ResumeThread解凍 DWORD WINAPI fun(void *p) {int i = 0;while (++i){printf("%d\n", i);if (i > 8000){//_endthread(); //用于線程內(nèi)部退出ExitThread(0); //同上 }}return 0; }//主線程,主導作用,管理調(diào)度其他線程 void main() {HANDLE hd = CreateThread(NULL, 0, fun, NULL, 0, NULL);system("pause");SuspendThread(hd); //凍結線程system("pause");ResumeThread(hd); //解凍線程system("pause");TerminateThread(hd,0); //外部強行結束線程 system("pause"); }7. 臨界區(qū) Critical Section:
#include <stdio.h> #include <stdlib.h> #include <process.h> #include <Windows.h>#define N 10 //#define N 100 臨界區(qū)最大線程是64 int num = 0;CRITICAL_SECTION cs1; //定義臨界區(qū),為結構體變量 CRITICAL_SECTION cs2;DWORD WINAPI add(void *p) {EnterCriticalSection(&cs1); //進入臨界區(qū),寫在for循環(huán)外,節(jié)省了在循環(huán)中反復進入和退出臨界區(qū)for (int i = 0; i < 10000; i++){//EnterCriticalSection(&cs1); num++;//LeaveCriticalSection(&cs1); }LeaveCriticalSection(&cs1); //退出臨界區(qū)return 0; }DWORD WINAPI sub(void *p) {EnterCriticalSection(&cs2); //進入臨界區(qū),寫在for循環(huán)外,節(jié)省了在循環(huán)中反復進入和退出臨界區(qū)for (int i = 0; i < 10000; i++){num--; }LeaveCriticalSection(&cs2); //退出臨界區(qū)return 0; }void main() {InitializeCriticalSection(&cs1); //初始化臨界區(qū)結構體InitializeCriticalSection(&cs2);{HANDLE hd[N];for (int i = 0; i < N; i++){hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL); //創(chuàng)建線程//WaitForSingleObject(hd[i], INFINITE); }WaitForMultipleObjects(N, hd, TRUE, INFINITE); //等待全部線程退出 printf("num=%d\n", num);}{HANDLE hd[N];for (int i = 0; i < N; i++){hd[i] = CreateThread(NULL, 0, sub, NULL, 0, NULL); //創(chuàng)建線程//WaitForSingleObject(hd[i], INFINITE); }WaitForMultipleObjects(N, hd, TRUE, INFINITE); //等待全部線程退出 printf("num=%d\n", num);}DeleteCriticalSection(&cs1); //釋放臨界區(qū)DeleteCriticalSection(&cs2);system("pause"); }?8. 線程通信-事件機制 event:
#include <stdio.h> #include <stdlib.h> #include <Windows.h>HANDLE event[3] = {0}; //事件 HANDLE hd[3] = { 0 }; //線程數(shù)組 DWORD WINAPI firstthread(void *p) {MessageBoxA(0, "1", "1", 0);printf("第1個線程執(zhí)行完成.\n");SetEvent(event[0]); //設置event信號return 0; }DWORD WINAPI secondthread(void *p) {WaitForSingleObject(event[0], INFINITE); //等待event信號出現(xiàn),才執(zhí)行下一步 MessageBoxA(0, "2", "2", 0);printf("第2個線程執(zhí)行完成.\n");return 0; }void main() {event[0] = CreateEvent(NULL, TRUE, FALSE, NULL); //創(chuàng)建事件event[1] = CreateEvent(NULL, TRUE, FALSE, NULL);hd[0] = CreateThread(NULL, 0, firstthread, NULL, 0, NULL); //創(chuàng)建線程hd[1] = CreateThread(NULL, 0, secondthread, NULL, 0, NULL);WaitForMultipleObjects(2, hd, TRUE, INFINITE);printf("全部完成!\n");system("pause"); } #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <memory.h>HANDLE event[4] = { 0 }; //事件 HANDLE hd[3] = { 0 }; //線程數(shù)組 char str[1024] = { 0 }; //代表聊天內(nèi)容的緩沖區(qū) CRITICAL_SECTION(cs); //臨界區(qū)//0 張通知媒婆 //1 媒婆發(fā)給李 //2 李通知媒婆 //3 媒婆發(fā)給張 DWORD WINAPI Zhang(void *p) {int i = 1;EnterCriticalSection(&cs); //進入臨界區(qū)memset(str, '\0', 1024);sprintf(str, "張第%d次說:I love you Li\n", i);LeaveCriticalSection(&cs); //離開臨界區(qū) Sleep(1000);SetEvent(event[0]);while (++i){WaitForSingleObject(event[3], INFINITE);EnterCriticalSection(&cs); //進入臨界區(qū)memset(str, '\0', 1024);sprintf(str, "張第%d次說:I love you Li\n", i);LeaveCriticalSection(&cs); //離開臨界區(qū) Sleep(1000);SetEvent(event[0]);}return 0; }DWORD WINAPI Li(void *p) {int i = 0;while (++i){WaitForSingleObject(event[1], INFINITE);EnterCriticalSection(&cs); //進入臨界區(qū)memset(str, '\0', 1024);sprintf(str,"李第%d次說:I love you too\n", i);LeaveCriticalSection(&cs); //離開臨界區(qū) Sleep(1000);SetEvent(event[2]);}return 0; }DWORD WINAPI show(void *p) {int i = 0;while (++i){WaitForSingleObject(event[0], INFINITE);EnterCriticalSection(&cs); //進入臨界區(qū)printf("媒婆傳遞:%s\n", str);LeaveCriticalSection(&cs); //離開臨界區(qū) Sleep(1000);SetEvent(event[1]);WaitForSingleObject(event[2], INFINITE);EnterCriticalSection(&cs);printf("媒婆傳遞:%s\n", str);LeaveCriticalSection(&cs);Sleep(1000);SetEvent(event[3]);}return 0; }void main() {InitializeCriticalSection(&cs);event[0] = CreateEvent(NULL, TRUE, FALSE, NULL); //創(chuàng)建事件event[1] = CreateEvent(NULL, TRUE, FALSE, NULL);event[2] = CreateEvent(NULL, TRUE, FALSE, NULL);event[3] = CreateEvent(NULL, TRUE, FALSE, NULL);hd[0] = CreateThread(NULL, 0, Zhang, NULL, 0, NULL); //創(chuàng)建線程hd[1] = CreateThread(NULL, 0, Li, NULL, 0, NULL);hd[2] = CreateThread(NULL, 0, show, NULL, 0, NULL);WaitForMultipleObjects(2, hd, TRUE, INFINITE);printf("全部完成!\n");DeleteCriticalSection(&cs);system("pause"); }9. 線程互斥量 mutex:
#include <stdio.h> #include <stdlib.h> #include <Windows.h>int num = 0;HANDLE mutex = NULL; //指針 DWORD WINAPI add(void *p) {WaitForSingleObject(mutex, INFINITE);for (int i = 0; i < 100000; i++){num++;}ReleaseMutex(mutex);return 0; }void main() {mutex = CreateMutex(NULL, FALSE, NULL); //創(chuàng)建互斥量if (mutex == NULL){//創(chuàng)建失敗 }HANDLE hd[10]; //線程互斥,同一個互斥量只能解決64個線程for (int i = 0; i < 10; i++) //創(chuàng)建10個線程 {hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL);if (mutex == NULL){//創(chuàng)建失敗 } }WaitForMultipleObjects(10, hd, TRUE, INFINITE);printf("%d\n", num);for (int i = 0; i < 10; i++) //關閉每一個線程資源 {CloseHandle(hd[i]);}CloseHandle(mutex); //關閉互斥量 system("pause"); }?10. 原子變量 valatile :
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <Windows.h>void main0401() {//release 優(yōu)化//volatile 原子操作 強制讀內(nèi)存 不考慮副本for (volatile int i = 0; i < INT_MAX; i++){}printf("over");system("pause"); }volatile int num = 20; //現(xiàn)代編譯器做了優(yōu)化,加不加volatile是一樣的 DWORD WINAPI msg(void *p) //讀 {int *px = (int *)p;while (1){int data = *px; //強制讀內(nèi)存printf("%d\n", data);Sleep(1000);} }DWORD WINAPI cmsg(void *p) //寫 {int *px = (int *)p;while (1){*px += 1;Sleep(10000);} }void main() {CreateThread(NULL, 0, msg, &num, 0, NULL);CreateThread(NULL, 0, cmsg, &num, 0, NULL);printf("over");system("pause"); } #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <Windows.h>int num = 0; //多個線程同時訪問一個變量會發(fā)生沖突,同時寫入 //線程安全:一個變量是線程安全,多線程同時讀寫沒有誤差 //臨界區(qū)(Critical Section)、事件機制(event)、互斥量(Mutex) //原子操作的速度要快于 臨界區(qū)(Critical Section)、事件機制(event)、互斥量(Mutex) DWORD WINAPI runX(void *p) {for (int i = 0; i < 10000; i++){//num++;InterlockedIncrement(&num); //num++保證是完整操作,我操作完成了后續(xù)才能繼續(xù)執(zhí)行 }return 0; }void main() {HANDLE hd[50];for (int i = 0; i < 50; i++){hd[i] = CreateThread(NULL, 0, runX, NULL, 0, NULL);}WaitForMultipleObjects(50, hd, TRUE, INFINITE);printf("%d\n", num);system("pause"); }?11. 定時器 timer :
#include <stdio.h> #include <stdlib.h> #include <Windows.h>//單獨定時器只能用于同步通信 void main0601() {HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL); //創(chuàng)建定時器if (timer == NULL){return;}LARGE_INTEGER time; // time.QuadPart = -20000000; //2秒//單位是10^-7秒 0.1微秒SetWaitableTimer(timer, &time, 0, NULL, 0, NULL); //設置定時器等待2秒if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0){printf("等待成功!\n");}else{printf("等待失敗!\n");}system("pause"); }HANDLE timer;DWORD WINAPI go1(void *p) {MessageBoxA(0, "1", "1", 0);timer = CreateWaitableTimer(NULL, TRUE, NULL); //創(chuàng)建定時器LARGE_INTEGER time; // time.QuadPart = -50000000; //2秒//單位是10^-7秒 0.1微秒SetWaitableTimer(timer, &time, 0, NULL, 0, NULL); //設置定時器等待2秒 }DWORD WINAPI go2(void *p) {WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0;MessageBoxA(0, "2", "2", 0);printf("等待成功!\n"); }void main() {HANDLE hd = CreateThread(NULL, 0, go1, NULL, 0, NULL);WaitForSingleObject(hd, INFINITE);if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0){CreateThread(NULL, 0, go2, NULL, 0, NULL);printf("等待成功!\n");}else{printf("等待失敗!\n");}system("pause"); }?
轉載于:https://www.cnblogs.com/si-lei/p/9480796.html
總結
- 上一篇: threading多线程模块
- 下一篇: [SDOI2013]直径 (树的直径,贪