C语言多线程编程一
1. Windows下同时打开多个对话框:
#include <Windows.h>
#include <process.h> //创建线程 void runmsg(void *p)
{
MessageBoxA(, "hello world", "hello china", ); } void main()
{
_beginthread(runmsg, , NULL); //启动线程,函数地址,把函数当做线程的入口点
_beginthread(runmsg, , NULL);
_beginthread(runmsg, , NULL);
_beginthread(runmsg, , 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(, "hello", "china", );
}
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 = ; i < ; i++)
{
hthread = CreateThread(
NULL, //安全属性
NULL, //堆栈大小
MyMseg, //线程的入口点
NULL, //函数的参数
, //立刻执行
&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[] = { , , , , , , , , , };
for (int i = ; i < ; i++)
{
HANDLE hd = (HANDLE) _beginthread(run, , &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 = ; //找到设置为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 == )
{
printf("线程%d结束查找,其他线程已经找到\n", ps->id);
return; } if (*pf == ps->findNum)
{
printf("线程%d结束查找,找到数据%d地址%p\n", ps->id, *pf, pf);
isfind = ;
return;
} } printf("线程%d结束查找\n", ps->id); } void main()
{
int a[] = { };
time_t ts;
unsigned int data = time(&ts);
srand(data); //随机数种子 for (int i = ; i < ; i++)
{
a[i] = rand() % ;
printf("%4d", a[i]);
if ((i+) % == ) //每10个打印一行
{
printf("\n");
}
} int num;
printf("输入要查询的数:\n");
scanf("%d", &num); struct findInfo info[]; //结构体数组,保存每个线程要查找的信息
for (int i = ; i < ;i++)
{
info[i].pstart = a + * i;
info[i].length = ;
info[i].findNum = num;
info[i].id = i; _beginthread(findIt, , &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 = ; //找到设置为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 == )
{
printf("线程%d结束查找,其他线程已经找到\n", ps->id);
return; } if (*pf == ps->findNum)
{
printf("线程%d结束查找,找到数据%d地址%p\n", ps->id, *pf, pf);
isfind = ;
return;
}
} printf("线程%d结束查找\n", ps->id);
} void main()
{
int a[] = { };
time_t ts;
unsigned int data = time(&ts);
srand(data); //随机数种子 for (int i = ; i < ; i++)
{
a[i] = rand() % ;
printf("%4d", a[i]);
if ((i+) % == ) //每10个打印一行
{
printf("\n");
}
} int num;
printf("输入要查询的数:\n");
scanf("%d", &num); struct findInfo info[N]; //结构体数组,保存每个线程要查找的信息
if (M%N == ) //前面能整除的情况
{
for (int i = ; 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, , &info[i]);
}
}
else //不能整除的情况
{
for (int i = ; 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, , &info[i]);
}
//info[N-1];
int i = N - ;
info[i].pstart = a + M / (N - ) * i;
info[i].length = M % (N - );
info[i].findNum = num;
info[i].id = i;
HANDLE hd = _beginthread(findIt, , &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 = ; //全局变量,多线程同时访问会发生冲突 //10 * 100 * 100
DWORD WINAPI myfun(void *p)
{
for (int i = ; i < ; i++)
{
EnterCriticalSection(&cs); //进入临界区
num++;
LeaveCriticalSection(&cs); //离开临界区
//Sleep(10);
}
return ;
} void main()
{
time_t start, end;
time(&start); HANDLE hd[];
for (int i = ; i < ; i++)
{
hd[i] = CreateThread(NULL, , myfun, NULL, , NULL);
//hd[i] = _beginthread(myfun, 0, NULL); //线程数组,数组的每一个元素都是一个线程
//WaitForSingleObject(hd[i], INFINITE); //等待单个的线程结束(同步)
}
WaitForMultipleObjects(, 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 = ;
while (++i)
{
printf("%d\n", i); if (i > )
{
//_endthread(); //用于线程内部退出
ExitThread(); //同上
} } return ;
} //主线程,主导作用,管理调度其他线程
void main()
{
HANDLE hd = CreateThread(NULL, , fun, NULL, , NULL); system("pause");
SuspendThread(hd); //冻结线程
system("pause");
ResumeThread(hd); //解冻线程
system("pause"); TerminateThread(hd,); //外部强行结束线程 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 = ; CRITICAL_SECTION cs1; //定义临界区,为结构体变量
CRITICAL_SECTION cs2; DWORD WINAPI add(void *p)
{
EnterCriticalSection(&cs1); //进入临界区,写在for循环外,节省了在循环中反复进入和退出临界区
for (int i = ; i < ; i++)
{
//EnterCriticalSection(&cs1);
num++;
//LeaveCriticalSection(&cs1);
}
LeaveCriticalSection(&cs1); //退出临界区 return ;
} DWORD WINAPI sub(void *p)
{
EnterCriticalSection(&cs2); //进入临界区,写在for循环外,节省了在循环中反复进入和退出临界区
for (int i = ; i < ; i++)
{
num--;
}
LeaveCriticalSection(&cs2); //退出临界区 return ;
} void main()
{
InitializeCriticalSection(&cs1); //初始化临界区结构体
InitializeCriticalSection(&cs2); {
HANDLE hd[N];
for (int i = ; i < N; i++)
{
hd[i] = CreateThread(NULL, , add, NULL, , NULL); //创建线程
//WaitForSingleObject(hd[i], INFINITE);
}
WaitForMultipleObjects(N, hd, TRUE, INFINITE); //等待全部线程退出 printf("num=%d\n", num);
} {
HANDLE hd[N];
for (int i = ; i < N; i++)
{
hd[i] = CreateThread(NULL, , sub, NULL, , 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[] = {}; //事件
HANDLE hd[] = { }; //线程数组 DWORD WINAPI firstthread(void *p)
{
MessageBoxA(, "", "", );
printf("第1个线程执行完成.\n"); SetEvent(event[]); //设置event信号
return ;
} DWORD WINAPI secondthread(void *p)
{
WaitForSingleObject(event[], INFINITE); //等待event信号出现,才执行下一步 MessageBoxA(, "", "", ); printf("第2个线程执行完成.\n");
return ;
} void main()
{
event[] = CreateEvent(NULL, TRUE, FALSE, NULL); //创建事件
event[] = CreateEvent(NULL, TRUE, FALSE, NULL); hd[] = CreateThread(NULL, , firstthread, NULL, , NULL); //创建线程
hd[] = CreateThread(NULL, , secondthread, NULL, , NULL); WaitForMultipleObjects(, 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[] = { }; //事件
HANDLE hd[] = { }; //线程数组
char str[] = { }; //代表聊天内容的缓冲区 CRITICAL_SECTION(cs); //临界区 //0 张通知媒婆
//1 媒婆发给李
//2 李通知媒婆
//3 媒婆发给张
DWORD WINAPI Zhang(void *p)
{
int i = ; EnterCriticalSection(&cs); //进入临界区
memset(str, '\0', );
sprintf(str, "张第%d次说:I love you Li\n", i);
LeaveCriticalSection(&cs); //离开临界区 Sleep();
SetEvent(event[]); while (++i)
{
WaitForSingleObject(event[], INFINITE); EnterCriticalSection(&cs); //进入临界区
memset(str, '\0', );
sprintf(str, "张第%d次说:I love you Li\n", i);
LeaveCriticalSection(&cs); //离开临界区 Sleep();
SetEvent(event[]); } return ;
} DWORD WINAPI Li(void *p)
{
int i = ;
while (++i)
{
WaitForSingleObject(event[], INFINITE); EnterCriticalSection(&cs); //进入临界区
memset(str, '\0', );
sprintf(str,"李第%d次说:I love you too\n", i);
LeaveCriticalSection(&cs); //离开临界区 Sleep();
SetEvent(event[]); } return ;
} DWORD WINAPI show(void *p)
{
int i = ;
while (++i)
{
WaitForSingleObject(event[], INFINITE); EnterCriticalSection(&cs); //进入临界区
printf("媒婆传递:%s\n", str);
LeaveCriticalSection(&cs); //离开临界区 Sleep();
SetEvent(event[]); WaitForSingleObject(event[], INFINITE);
EnterCriticalSection(&cs);
printf("媒婆传递:%s\n", str);
LeaveCriticalSection(&cs); Sleep();
SetEvent(event[]);
} return ;
} void main()
{
InitializeCriticalSection(&cs); event[] = CreateEvent(NULL, TRUE, FALSE, NULL); //创建事件
event[] = CreateEvent(NULL, TRUE, FALSE, NULL);
event[] = CreateEvent(NULL, TRUE, FALSE, NULL);
event[] = CreateEvent(NULL, TRUE, FALSE, NULL); hd[] = CreateThread(NULL, , Zhang, NULL, , NULL); //创建线程
hd[] = CreateThread(NULL, , Li, NULL, , NULL);
hd[] = CreateThread(NULL, , show, NULL, , NULL); WaitForMultipleObjects(, hd, TRUE, INFINITE);
printf("全部完成!\n"); DeleteCriticalSection(&cs); system("pause");
}
9. 线程互斥量 mutex:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h> int num = ; HANDLE mutex = NULL; //指针 DWORD WINAPI add(void *p)
{
WaitForSingleObject(mutex, INFINITE);
for (int i = ; i < ; i++)
{
num++;
}
ReleaseMutex(mutex); return ;
} void main()
{
mutex = CreateMutex(NULL, FALSE, NULL); //创建互斥量
if (mutex == NULL)
{
//创建失败
} HANDLE hd[]; //线程互斥,同一个互斥量只能解决64个线程 for (int i = ; i < ; i++) //创建10个线程
{
hd[i] = CreateThread(NULL, , add, NULL, , NULL);
if (mutex == NULL)
{
//创建失败
}
} WaitForMultipleObjects(, hd, TRUE, INFINITE); printf("%d\n", num); for (int i = ; i < ; 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 = ; i < INT_MAX; i++)
{ } printf("over");
system("pause");
} volatile int num = ; //现代编译器做了优化,加不加volatile是一样的 DWORD WINAPI msg(void *p) //读
{
int *px = (int *)p; while ()
{
int data = *px; //强制读内存
printf("%d\n", data); Sleep();
}
} DWORD WINAPI cmsg(void *p) //写
{
int *px = (int *)p; while ()
{ *px += ; Sleep();
}
} void main()
{
CreateThread(NULL, , msg, &num, , NULL);
CreateThread(NULL, , cmsg, &num, , NULL); printf("over");
system("pause");
}
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <Windows.h> int num = ; //多个线程同时访问一个变量会发生冲突,同时写入
//线程安全:一个变量是线程安全,多线程同时读写没有误差
//临界区(Critical Section)、事件机制(event)、互斥量(Mutex)
//原子操作的速度要快于 临界区(Critical Section)、事件机制(event)、互斥量(Mutex)
DWORD WINAPI runX(void *p)
{
for (int i = ; i < ; i++)
{
//num++;
InterlockedIncrement(&num); //num++保证是完整操作,我操作完成了后续才能继续执行
} return ;
} void main()
{
HANDLE hd[];
for (int i = ; i < ; i++)
{
hd[i] = CreateThread(NULL, , runX, NULL, , NULL);
}
WaitForMultipleObjects(, 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 = -; //2秒
//单位是10^-7秒 0.1微秒
SetWaitableTimer(timer, &time, , NULL, , NULL); //设置定时器等待2秒 if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0)
{
printf("等待成功!\n");
}
else
{
printf("等待失败!\n");
} system("pause");
} HANDLE timer; DWORD WINAPI go1(void *p)
{
MessageBoxA(, "", "", ); timer = CreateWaitableTimer(NULL, TRUE, NULL); //创建定时器
LARGE_INTEGER time; //
time.QuadPart = -; //2秒
//单位是10^-7秒 0.1微秒
SetWaitableTimer(timer, &time, , NULL, , NULL); //设置定时器等待2秒
} DWORD WINAPI go2(void *p)
{
WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0;
MessageBoxA(, "", "", );
printf("等待成功!\n");
} void main()
{
HANDLE hd = CreateThread(NULL, , go1, NULL, , NULL); WaitForSingleObject(hd, INFINITE); if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0)
{
CreateThread(NULL, , go2, NULL, , NULL);
printf("等待成功!\n");
}
else
{
printf("等待失败!\n");
} system("pause");
}
C语言多线程编程一的更多相关文章
- C++多线程编程一
1.C++多线程初步: #include <iostream> #include <thread> #include <Windows.h> using names ...
- Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别
Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...
- python和C语言混编的几种方式
Python这些年风头一直很盛,占据了很多领域的位置,Web.大数据.人工智能.运维均有它的身影,甚至图形界面做的也很顺,乃至full-stack这个词语刚出来的时候,似乎就是为了描述它. Pytho ...
- [转]c++多线程编程之pthread线程深入理解
多线程编程之pthread线程深入理解 Pthread是 POSIX threads 的简称,是POSIX的线程标准. 前几篇博客已经能给你初步的多线程概念.在进一 ...
- iOS多线程编程之NSThread的使用
目录(?)[-] 简介 iOS有三种多线程编程的技术分别是 三种方式的有缺点介绍 NSThread的使用 NSThread 有两种直接创建方式 参数的意义 PS不显式创建线程的方法 下载图片的例子 ...
- 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解
Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解 多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...
- iOS多线程编程之NSThread的使用(转)
本文由http://blog.csdn.net/totogo2010/原创 1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation ...
- [转] iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用
介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...
- [转] iOS多线程编程之NSOperation和NSOperationQueue的使用
<iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...
随机推荐
- 自己制作winhex的模板
winhex有很多的官方模板,可以在网上下载(后缀tpl)并放至它的安装目录,即可使用.不过要是自己能自己制作,这才好玩,不是么?! 打开模板管理器,可以选中其中一个模板,下面有应用,有编辑,你点开编 ...
- placement new
placement new就是把原本new做的两步工作分开来.第一步你自己分配内存,第二步你调用类的构造函数在自己分配的内存上构建新的对象. class Foo { float f; public: ...
- oracle 基本函数小例子--查询身高段分数段
select * from student order by id drop table student select * from oracletest create table student( ...
- sqlserver select 查询字段if判断用法
SELECT TOP 1000 [id], case when group_id>1 then 'vip' else '普通会员' end F ...
- python socket编程入门(编写server实例)-乾颐堂
python 编写server的步骤: 1. 第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket( family, type ) family参 ...
- CHANGE DETECTION IN ANGULAR 2
In this article I will talk in depth about the Angular 2 change detection system. HIGH-LEVEL OVERVIE ...
- mongo学习- 副本集 大多数原则
副本集中有一个重要的概念“大多数”,意思是说,选择主节点需要大多数决定(本人亲自做了实验) 步骤: 1.开启副本集(如果没有配置好 副本集的 亲参考我的上篇文章 https://www.cnblog ...
- struct 和union的区别
union ( 共用体):构造数据类型,也叫联合体 用途:使几个不同类型的变量共占一段内存(相互覆盖) struct ( 结构体 ):是一种构造类型 用途: 把不同的数据组合成一个整体——自定义数据 ...
- Google Tango SDK下载
Tango SDK files谷歌Tango开发包 The Tango SDK is under active development; please keep this in mind as you ...
- 深水划水队项目---七天冲刺之day5
站立式会议: 因为今天有成员回家,不能进行线下站立式会议,只能线上进行语音聊天 工作进度: 昨天完成的任务: 游戏功能的基本实现 商讨出如何实现游戏中的难度选择功能与道具功能 商讨出站立式会议能线下 ...