c++ sleep函数_C++ this_thread::sleep_for

this_thread::sleep_for

阻塞当前线程执行,至少经过指定的 sleep_duration 。

声明:此系列为个人工作及学习所遇到问题的总结,相关参考的部分我都会以参考**的形式标注出来。

此函数可能阻塞长于 sleep_duration ,因为调度或资源争议延迟。

标准库建议用稳定时钟度量时长。若实现用系统时间代替,则等待时间亦可能对时钟调节敏感。

参数    

代码示例

#include 

out

等待多久了
等了 2s
若你对人工智能(CV/NLP)、C++/python编程、互联网就业及发展有兴趣,欢迎点赞关注和收藏。谢谢鼓励!!!

C++相关知识:

Anxjing.AI:C++ this_thread::sleep_for​zhuanlan.zhihu.com
0edac4abdd0e51af5c56d0bfd2cf056d.png
Anxjing.AI:C++ Lambda表达式​zhuanlan.zhihu.com
8bb2c2b418f05d2cc1fe4a77149c175a.png
Anxjing.AI:C++并发_condition_variable​zhuanlan.zhihu.com
49eb491a8abae8805bd930fd625d45cb.png
Anxjing.AI:生产者-消费者模型​zhuanlan.zhihu.com
0ad5b286c1c442483990aec0855ec2fd.png
Anxjing.AI:C++预处理指令​zhuanlan.zhihu.com
7729042e3276208cf910536d0a3e54fb.png
Anxjing.AI:C++工具:Cmake​zhuanlan.zhihu.com
69d1bac962f2c4b3c28e9d060f0f0fd0.png
Anxjing.AI:SSH 学习​zhuanlan.zhihu.com
b0475e59a7f610e1449642d964ad0a58.png
Anxjing.AI:记录C++阶段性学习一​zhuanlan.zhihu.com
cf6bb88c39c8be1ba9ecc86f65c63505.png
Anxjing.AI:DesignPatterns C++:单例模式​zhuanlan.zhihu.com
fd818b7638db4be1dbebeda54424e6e9.png
Anxjing.AI:C++基础:map简析​zhuanlan.zhihu.com
a5cab97c2ea0ee4a1d9f993d1c30da54.png
Anxjing.AI:C++基础:memset函数简析​zhuanlan.zhihu.com
6f7da64e3eca9a0b23ddf9fd8a4430ca.png
Anxjing.AI:C++基础:break&continue区别​zhuanlan.zhihu.com
11792112b5bc24e00d516caf230ff0bf.png
Anxjing.AI:C++基础:指针和引用的区别​zhuanlan.zhihu.com
81db3b07c238774440f6cc0ee88e21b3.png
Anxjing.AI:C++中::和:, .和->的作用和区别?​zhuanlan.zhihu.com
89d7d927c344ba5ec995870925c7f0c1.png
Anxjing.AI:string中c_str()的使用方法和特性​zhuanlan.zhihu.com
a5cab97c2ea0ee4a1d9f993d1c30da54.png
Anxjing.AI:C ++ strcpy()和strncpy()函数​zhuanlan.zhihu.com
5c1d1b66efd82c797f6541026253b278.png
Anxjing.AI:C++基础-关键字virtual​zhuanlan.zhihu.com
ec236ff700ed0b33b0031c5818b5b8be.png
Anxjing.AI:C++基础-函数重载​zhuanlan.zhihu.com
f1f46994c3b477eb00ec03eb143ed69c.png
Anxjing.AI:C++基础-static​zhuanlan.zhihu.com
fd6873e2cfa351828a7407215d29e7f2.png
Anxjing.AI:C++基础:判断文件是否存在的方法​zhuanlan.zhihu.com
003acf50ec082eb1823677346a8d6bf8.png
Anxjing.AI:C++基础-strstr查找子串​zhuanlan.zhihu.com
e06c2a317e74eb6bf83806842eb4d41f.png
Anxjing.AI:C++基础:std::thread多线程​zhuanlan.zhihu.com
f646812c77c0474079c119bd9de0b0d5.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include<windows.h> #include<fstream.h> #include<stdio.h> #include<string> #include<conio.h> //定义一些常量; //本程序允许的最大临界区数; #define MAX_BUFFER_NUM 10 //秒到微秒的乘法因子; #define INTE_PER_SEC 1000 //本程序允许的生产和消费线程的总数; #define MAX_THREAD_NUM 64 //定义一个结构,记录在测试文件中指定的每一个线程的参数 struct ThreadInfo { int serial; //线程序列号 char entity; //是P还是C double delay; //线程延迟 int thread_request[MAX_THREAD_NUM]; //线程请求队列 int n_request; //请求个数 }; //全局变量的定义 //临界区对象的声明,用于管理缓冲区的互斥访问; int Buffer_Critical[MAX_BUFFER_NUM]; //缓冲区声明,用于存放产品; ThreadInfo Thread_Info[MAX_THREAD_NUM]; //线程信息数组; HANDLE h_Thread[MAX_THREAD_NUM]; //用于存储每个线程句柄的数组; HANDLE empty_semaphore; //一个信号量; HANDLE h_mutex; //一个互斥量; HANDLE h_Semaphore[MAX_THREAD_NUM]; //生产者允许消费者开始消费的信号量; CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM]; DWORD n_Thread = 0; //实际的线程的数目; DWORD n_Buffer_or_Critical; //实际的缓冲区或者临界区的数目; //生产消费及辅助函数的声明 void Produce(void *p); void Consume(void *p); bool IfInOtherRequest(int); int FindProducePositon(); int FindBufferPosition(int); int main(int argc, char **argv) { //声明所需变量; DWORD wait_for_all; ifstream inFile; if (argc!=2) { printf("Usage:%s <File>\n",argv[0]); return 1; } //初始化缓冲区; for(int i=0;i< MAX_BUFFER_NUM;i++) Buffer_Critical[i] = -1; //初始化每个线程的请求队列; for(int j=0;j<MAX_THREAD_NUM;j++) { for(int k=0;k<MAX_THREAD_NUM;k++) Thread_Info[j].thread_request[k] = -1; Thread_Info[j].n_request = 0; } //初始化临界区; for(i =0;i< MAX_BUFFER_NUM;i++) InitializeCriticalSection(&PC_Critical[i]); //打开输入文件,按照规定的格式提取线程等信息; inFile.open(argv[1]); //从文件中获得实际的缓冲区的数目,即测试文件第一行的信息; inFile >> n_Buffer_or_Critical; inFile.get(); // 读取测试文件中的空格,将文件指针指向下一行; printf("输入文件是:\n"); //回显获得的缓冲区的数目信息; printf("%d \n",(int) n_Buffer_or_Critical); //提取每个线程的信息到相应数据结构中; while(inFile){ inFile >> Thread_Info[n_Thread].serial; inFile >> Thread_Info[n_Thread].entity; inFile >> Thread_Info[n_Thread].delay; char c; inFile.get(c); while(c!='\n'&& !inFile.eof()) { inFile>> Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++]; inFile.get(c); } n_Thread++; } //回显获得的线程信息,便于确认正确性; for(j=0;j<(int) n_Thread;j++) { int Temp_serial = Thread_Info[j].serial; char Temp_entity = Thread_Info[j].entity; double Temp_delay = Thread_Info[j].delay; printf(" \nthread%2d %c %f ",Temp_serial,Temp_entity,Temp_delay); int Temp_request = Thread_Info[j].n_request; for(int k=0;k<Temp_request;k++) printf(" %d ", Thread_Info[j].thread_request[k]); cout<<endl; } printf("\n\n"); //创建在模拟过程中几个必要的信号量 empty_semaphore = CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical, "semaphore_for_empty"); h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update"); //下面这个循环用线程的ID号来为相应生产线程的产品读写时所 //使用的同步信号量命名; for(j=0;j<(int)n_Thread;j++) { char lp[]="semaphore_for_produce_"; int temp =j; while(temp){ char c = (char)(temp%10); strcat(lp,&c); temp/=10; } h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp); } //创建生产者和消费者线程; for(i =0;i< (int) n_Thread;i++) { if(Thread_Info[i].entity =='P') h_Thread[i]= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce), &(Thread_Info[i]),0,NULL); else h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume), &(Thread_Info[i]),0,NULL); } //主程序等待各个线程的动作结束; wait_for_all = WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1); printf(" \n \nALL Producer and consumer have finished their work. \n"); printf("Press any key to quit!\n"); _getch(); return 0; } //确认是否还有对同一产品的消费请求未执行; bool IfInOtherRequest(int req) { for(int i=0;i<n_Thread;i++) for(int j=0;j<Thread_Info[i].n_request;j++) if(Thread_Info[i].thread_request[j] == req) return TRUE; return FALSE; } //找出当前可以进行产品生产的空缓冲区位置; int FindProducePosition() { int EmptyPosition; for (int i =0;i<n_Buffer_or_Critical;i++) if(Buffer_Critical[i] == -1) { EmptyPosition = i; //用下面这个特殊值表示本缓冲区正处于被写状态; Buffer_Critical[i] = -2; break; } return EmptyPosition; } //找出当前所需生产者生产的产品的位置; int FindBufferPosition(int ProPos) { int TempPos; for (int i =0 ;i<n_Buffer_or_Critical;i++) if(Buffer_Critical[i]==ProPos){ TempPos = i; break; } return TempPos; } //生产者进程 void Produce(void *p) { //局部变量声明; DWORD wait_for_semaphore,wait_for_mutex,m_delay; int m_serial; //获得本线程的信息; m_serial = ((ThreadInfo*)(p))->serial; m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC); Sleep(m_delay); //开始请求生产 printf("Producer %2d sends the produce require.\n",m_serial); //互斥访问下一个可用于生产的空临界区,实现写写互斥; wait_for_mutex = WaitForSingleObject(h_mutex,-1); //确认有空缓冲区可供生产,同时将空位置数empty减1;用于生产者和消费者的同步; //若没有则一直等待,直到消费者进程释放资源为止; wait_for_semaphore = WaitForSingleObject(empty_semaphore,-1); int ProducePos = FindProducePosition(); ReleaseMutex(h_mutex); //生产者在获得自己的空位置并做上标记后,以下的写操作在生产者之间可以并发; //核心生产步骤中,程序将生产者的ID作为产品编号放入,方便消费者识别; printf("Producer %2d begin to produce at position %2d.\n",m_serial,ProducePos); Buffer_Critical[ProducePos] = m_serial; printf("Producer %2d finish producing :\n ",m_serial); printf(" position[ %2d ]:%3d \n\n" ,ProducePos,Buffer_Critical[ProducePos]); //使生产者写的缓冲区可以被多个消费者使用,实现读写同步; ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL); } //消费者进程 void Consume(void * p) { //局部变量声明; DWORD wait_for_semaphore,m_delay; int m_serial,m_requestNum; //消费者的序列号和请求的数目; int m_thread_request[MAX_THREAD_NUM]; //本消费线程的请求队列; //提取本线程的信息到本地; m_serial = ((ThreadInfo*)(p))->serial; m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC); m_requestNum = ((ThreadInfo *)(p))->n_request; for (int i = 0;i<m_requestNum;i++) m_thread_request[i] = ((ThreadInfo*)(p))->thread_request[i]; Sleep(m_delay); //循环进行所需产品的消费 for(i =0;i<m_requestNum;i++){ //请求消费下一个产品 printf("Consumer %2d request to consume %2d product\n",m_serial,m_thread_request[i]); //如果对应生产者没有生产,则等待;如果生产了,允许的消费者数目-1;实现了读写同步; wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1); //查询所需产品放到缓冲区的号 int BufferPos=FindBufferPosition(m_thread_request[i]); //开始进行具体缓冲区的消费处理,读和读在该缓冲区上仍然是互斥的; //进入临界区后执行消费动作;并在完成此次请求后,通知另外的消费者本处请求已 //经满足;同时如果对应的产品使用完毕,就做相应处理;并给出相应动作的界面提 //示;该相应处理指将相应缓冲区清空,并增加代表空缓冲区的信号量; EnterCriticalSection(&PC_Critical[BufferPos]); printf("Consumer %2d begin to consume %2d product \n",m_serial,m_thread_request[i]); ((ThreadInfo*)(p))->thread_request[i] =-1; if(!IfInOtherRequest(m_thread_request[i])) { Buffer_Critical[BufferPos] = -1; //-1标记缓冲区为空; printf("Consumer %2d finish consuming %2d:\n ",m_serial,m_thread_request[i]); printf(" position[ %2d ]:%3d \n\n" ,BufferPos,Buffer_Critical[BufferPos]); ReleaseSemaphore(empty_semaphore,1,NULL); } else { printf("Consumer %2d finish consuming product %2d\n\n ",m_serial,m_thread_request[i]); } //离开临界区 LeaveCriticalSection(&PC_Critical[BufferPos]); } }
1. 创建一个基于对话框的应用程序。并增加如图所示控件;分别为3个进度条控件关联三个进度条类型的变量;并在对话框的初始化函数中,设定进度条的范围;为编辑框关联一个整型的变量;为12个按钮添加消息处理函数; 2. 定义结构体:用做线程函数的参数传递 typedef struct Threadinfo{ CProgressCtrl *progress;//进度条对象 int speed; //进度条速度 int pos; //进度条位置 } thread,*lpthread; 3. 为对话框增加三个句柄,用于标识各个线程; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 在增加三个结构体类型的变量,用做线程函数的参数传递; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 4. 新增一个静态的全局变量,用于记录所有线程的状态:static int GlobalVar=10000; 5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID pthread);//线程入口函数 6. 在启动按钮的消息处理函数中编写如下代码: thread1.progress=&m_progress1;//进度条对象 thread1.speed=100;//速度 thread1.pos=0;//初始位置 hThread1=CreateThread(NULL,0,ThreadFun,&thread1;,0,0);//创建并开始线程 if (!hThread1) { MessageBox("创建线程失败"); } 7. 编写线程函数(一般是一个死循环,或者需要花费时间很长的算法!否者就失去了多线程的意义) DWORD WINAPI ThreadFun(LPVOID pthread) //线程入口函数 { lpthread temp=(lpthread)pthread;//参数强制转换为结构体类型 temp->progress->SetPos(temp->pos); //设置被传递过来的进度条的位置 while(temp->posspeed); /设置速度 temp->pos++; //增加进度 temp->progress->SetPos(temp->pos); //设置进度条的新位置 GlobalVar--; if(temp->pos==20) { temp->pos=0; //进度条满则归0 } } return true; } 8. 在挂起按钮函数中,编写如下代码: if(SuspendThread(hThread1)==0xFFFFFFFF) { MessageBox("挂起失败!进程可能已经死亡或未创建!"); return; } 9. 在执行按钮函数中,编写如下代码: if(ResumeThread(hThread1)==0xFFFFFFFF) { MessageBox("执行失败!进程可能已经死亡或未创建!"); return; } 10. 在停止按钮函数中,编写如下代码: if(TerminateThread(hThread1,0))//前些终止线程 { CloseHandle(hThread1);//销毁线程句柄 } else { MessageBox("终止进程失败!"); } 11. 为应用程序添加WM_TIMER消息,实时更新全局变量的值到编辑框;
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。 目 录 第1部分C++ 多线程系统编程 第1章线程安全的对象生命期管理3 1.1当析构函数遇到多线程. . . . . . . . . . . . . . . . .. . . . . . . . . . . 3 1.1.1线程安全的定义. . . . . . . . . . . . . . . . .. . . . . . . . . . . 4 1.1.2MutexLock 与MutexLockGuard. . . . . . . . . . . . . . . . . . . . 4 1.1.3一个线程安全的Counter 示例.. . . . . . . . . . . . . . . . . . . 4 1.2对象的创建很简单. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 5 1.3销毁太难. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 7 1.3.1mutex 不是办法. . . . . . . . . . . . . . . . . . . .. . . . . . . . 7 1.3.2作为数据成员的mutex 不能保护析构.. . . . . . . . . . . . . . 8 1.4线程安全的Observer 有多难.. . . . . . . . . . . . . . . . . . . . . . . . 8 1.5原始指针有何不妥. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 11 1.6神器shared_ptr/weak_ptr . . . . . . . . . .. . . . . . . . . . . . . . . . 13 1.7插曲:系统地避免各种指针错误. . . . . . . . . . . . . . . . .. . . . . . 14 1.8应用到Observer 上.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.9再论shared_ptr 的线程安全.. . . . . . . . . . . . . . . . . . . . . . . . 17 1.10shared_ptr 技术与陷阱. . . .. . . . . . . . . . . . . . . . . . . . . . . . 19 1.11对象池. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 21 1.11.1enable_shared_from_this . . . . . . . . . . . . . . . . . . . . . . 23 1.11.2弱回调. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 24 1.12替代方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 26 1.13心得与小结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 26 1.14Observer 之谬. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 第2章线程同步精要 2.1互斥器(mutex). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.1.1只使用非递归的mutex . . . . . . . . . . . . . .. . . . . . . . . . 33 2.1.2死锁. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 35 2.2条件变量(condition variable). . . . . . . . . .

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值