C语言多线程编程一
1. Windows下同时打开多个对话框:
#include <Windows.h> #include <process.h> //创建线程void runmsg(void *p) {MessageBoxA(0, "hello world", "hello china", 0);}void main() {_beginthread(runmsg, 0, NULL); //启动线程,函数地址,把函数当做线程的入口点_beginthread(runmsg, 0, NULL);_beginthread(runmsg, 0, NULL);_beginthread(runmsg, 0, NULL);system("pause"); }2. 多线程实现同步和异步:
#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; //保存线程编号//异步执行://for (int i = 0; i < 5; i++)//{// hthread = CreateThread(// NULL, //安全属性// NULL, //堆栈大小// MyMseg, //线程的入口点// NULL, //函数的参数// 0, //立刻执行// &threadid //保存线程的id// );//}//多线程实现同步: for (int i = 0; i < 5; i++){hthread = CreateThread(NULL, //安全属性NULL, //堆栈大小MyMseg, //线程的入口点NULL, //函数的参数0, //立刻执行&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> //生成随机数 #include <process.h>int isfind = 0; //找到设置为1,其他线程就不再查找struct findInfo {int *pstart; //线程检索的首地址int length; //检索的数据长度int findNum; //需要查找的数据 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结束查找,其他线程已经找到\n", ps->id);return;}if (*pf == ps->findNum){printf("线程%d结束查找,找到数据%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); //随机数种子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("输入要查询的数:\n");scanf("%d", &num);struct findInfo info[10]; //结构体数组,保存每个线程要查找的信息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]); //调用线程 }system("pause"); }4. 多线程切割:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <time.h> //生成随机数 #include <process.h>int isfind = 0; //找到设置为1,其他线程就不再查找struct findInfo {int *pstart; //线程检索的首地址int length; //检索的数据长度int findNum; //需要查找的数据 int id; //线程的编号 };#define M 100 //数据 #define N 8 //线程数量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结束查找,其他线程已经找到\n", ps->id);return;}if (*pf == ps->findNum){printf("线程%d结束查找,找到数据%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); //随机数种子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("输入要查询的数:\n");scanf("%d", &num);struct findInfo info[N]; //结构体数组,保存每个线程要查找的信息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; //临界区,全局int num = 0; //全局变量,多线程同时访问会发生冲突//10 * 100 * 100 DWORD WINAPI myfun(void *p) {for (int i = 0; i < 100; i++){EnterCriticalSection(&cs); //进入临界区num++;LeaveCriticalSection(&cs); //离开临界区//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); //线程数组,数组的每一个元素都是一个线程//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 创建线程 //_endthread ExitThread 内部结束线程 TerminateThread 外部强制结束 //SuspendThread冻结 ResumeThread解冻 DWORD WINAPI fun(void *p) {int i = 0;while (++i){printf("%d\n", i);if (i > 8000){//_endthread(); //用于线程内部退出ExitThread(0); //同上 }}return 0; }//主线程,主导作用,管理调度其他线程 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. 临界区 Critical Section:
#include <stdio.h> #include <stdlib.h> #include <process.h> #include <Windows.h>#define N 10 //#define N 100 临界区最大线程是64 int num = 0;CRITICAL_SECTION cs1; //定义临界区,为结构体变量 CRITICAL_SECTION cs2;DWORD WINAPI add(void *p) {EnterCriticalSection(&cs1); //进入临界区,写在for循环外,节省了在循环中反复进入和退出临界区for (int i = 0; i < 10000; i++){//EnterCriticalSection(&cs1); num++;//LeaveCriticalSection(&cs1); }LeaveCriticalSection(&cs1); //退出临界区return 0; }DWORD WINAPI sub(void *p) {EnterCriticalSection(&cs2); //进入临界区,写在for循环外,节省了在循环中反复进入和退出临界区for (int i = 0; i < 10000; i++){num--; }LeaveCriticalSection(&cs2); //退出临界区return 0; }void main() {InitializeCriticalSection(&cs1); //初始化临界区结构体InitializeCriticalSection(&cs2);{HANDLE hd[N];for (int i = 0; i < N; i++){hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL); //创建线程//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); //创建线程//WaitForSingleObject(hd[i], INFINITE); }WaitForMultipleObjects(N, hd, TRUE, INFINITE); //等待全部线程退出 printf("num=%d\n", num);}DeleteCriticalSection(&cs1); //释放临界区DeleteCriticalSection(&cs2);system("pause"); }8. 线程通信-事件机制 event:
#include <stdio.h> #include <stdlib.h> #include <Windows.h>HANDLE event[3] = {0}; //事件 HANDLE hd[3] = { 0 }; //线程数组 DWORD WINAPI firstthread(void *p) {MessageBoxA(0, "1", "1", 0);printf("第1个线程执行完成.\n");SetEvent(event[0]); //设置event信号return 0; }DWORD WINAPI secondthread(void *p) {WaitForSingleObject(event[0], INFINITE); //等待event信号出现,才执行下一步 MessageBoxA(0, "2", "2", 0);printf("第2个线程执行完成.\n");return 0; }void main() {event[0] = CreateEvent(NULL, TRUE, FALSE, NULL); //创建事件event[1] = CreateEvent(NULL, TRUE, FALSE, NULL);hd[0] = CreateThread(NULL, 0, firstthread, NULL, 0, NULL); //创建线程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 }; //线程数组 char str[1024] = { 0 }; //代表聊天内容的缓冲区 CRITICAL_SECTION(cs); //临界区//0 张通知媒婆 //1 媒婆发给李 //2 李通知媒婆 //3 媒婆发给张 DWORD WINAPI Zhang(void *p) {int i = 1;EnterCriticalSection(&cs); //进入临界区memset(str, '\0', 1024);sprintf(str, "张第%d次说:I love you Li\n", i);LeaveCriticalSection(&cs); //离开临界区 Sleep(1000);SetEvent(event[0]);while (++i){WaitForSingleObject(event[3], INFINITE);EnterCriticalSection(&cs); //进入临界区memset(str, '\0', 1024);sprintf(str, "张第%d次说:I love you Li\n", i);LeaveCriticalSection(&cs); //离开临界区 Sleep(1000);SetEvent(event[0]);}return 0; }DWORD WINAPI Li(void *p) {int i = 0;while (++i){WaitForSingleObject(event[1], INFINITE);EnterCriticalSection(&cs); //进入临界区memset(str, '\0', 1024);sprintf(str,"李第%d次说:I love you too\n", i);LeaveCriticalSection(&cs); //离开临界区 Sleep(1000);SetEvent(event[2]);}return 0; }DWORD WINAPI show(void *p) {int i = 0;while (++i){WaitForSingleObject(event[0], INFINITE);EnterCriticalSection(&cs); //进入临界区printf("媒婆传递:%s\n", str);LeaveCriticalSection(&cs); //离开临界区 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); //创建事件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); //创建线程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); //创建互斥量if (mutex == NULL){//创建失败 }HANDLE hd[10]; //线程互斥,同一个互斥量只能解决64个线程for (int i = 0; i < 10; i++) //创建10个线程 {hd[i] = CreateThread(NULL, 0, add, NULL, 0, NULL);if (mutex == NULL){//创建失败 } }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 优化//volatile 原子操作 强制读内存 不考虑副本for (volatile int i = 0; i < INT_MAX; i++){}printf("over");system("pause"); }volatile int num = 20; //现代编译器做了优化,加不加volatile是一样的 DWORD WINAPI msg(void *p) //读 {int *px = (int *)p;while (1){int data = *px; //强制读内存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; //多个线程同时访问一个变量会发生冲突,同时写入 //线程安全:一个变量是线程安全,多线程同时读写没有误差 //临界区(Critical Section)、事件机制(event)、互斥量(Mutex) //原子操作的速度要快于 临界区(Critical Section)、事件机制(event)、互斥量(Mutex) DWORD WINAPI runX(void *p) {for (int i = 0; i < 10000; i++){//num++;InterlockedIncrement(&num); //num++保证是完整操作,我操作完成了后续才能继续执行 }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); //创建定时器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); //创建定时器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]直径 (树的直径,贪