多线程编程(c++多线程编程)
多线程编程(c++多线程编程)
多线程编程可以说是每个程序员的基本功,也是开发中的难点之一。以Linux C为例,介绍了线程的创建和几种常见的线程同步方式。最后对多线程编程进行了总结和思考,并给出了代码示例。
首先,创建一个线程
多线程编程的第一步是创建线程。创建一个线程实际上增加了一个控制进程,使得同一个进程中的多个控制进程并发或并行执行。
创建线程函数。其他功能不在此列。可以参考pthread.h
#includeintpthread_create(pthread_t*restrictthread,/*线程id*/constpthread_attr_t*restrictattr,/*线程属性,默认可置为NULL,表示线程属性取缺省值*/void*(*start_routine)(void*),/*线程入口函数*/void*restrictarg/*线程入口函数的参数*/);
代码示例:
#include#include#include#include#includechar*thread_func1(void*arg){pid_tpid=getpid();pthread_ttid=pthread_self();printf(“%spid:%u,tid:%u(0x%x)\n”,(char*)arg,(unsignedint)pid,(unsignedint)tid,(unsignedint)tid);char*msg=“thread_func1”;returnmsg;}void*thread_func2(void*arg){pid_tpid=getpid();pthread_ttid=pthread_self();printf(“%spid:%u,tid:%u(0x%x)\n”,(char*)arg,(unsignedint)pid,(unsignedint)tid,(unsignedint)tid);char*msg=“thread_func2“;while(1){printf(“%srunning\n”,msg);sleep(1);}returnNULL;}intmain(){pthread_ttid1,tid2;if(pthread_create(&tid1,NULL,(void*)thread_func1,“newthread:”)!=0){printf(“pthread_createerror.”);exit(EXIT_FAILURE);}if(pthread_create(&tid2,NULL,(void*)thread_func2,“newthread:”)!=0){printf(“pthread_createerror.”);exit(EXIT_FAILURE);}pthread_detach(tid2);char*rev=NULL;pthread_join(tid1,(void*)&rev);printf(“%sreturn.\n”,rev);pthread_cancel(tid2);printf(“mainthreadend.\n”);return0;}
第二,线程同步
有时候我们需要多个线程相互配合执行,然后需要线程之间的同步。线程同步的常用方法有:
互相排斥
旗语
条件变量
让我们看一个没有线程同步的例子:
#include#include#include#include#include#defineLEN100000intnum=0;void*thread_func(void*arg){for(inti=0;in;structdata*tmp=phead;phead=phead->next;free(tmp);}}pthread_mutex_unlock(&mlock);if(count>LIMIT)break;}printf(“consumercount=%d\n”,count);}intmain(){pthread_ttid1,tid2;pthread_create(&tid1,NULL,(void*)producer,NULL);pthread_create(&tid2,NULL,(void*)consumer,NULL);pthread_join(tid1,NULL);pthread_join(tid2,NULL);return0;}
分享更多关于Linux后端开发网络底层原理的知识。点击跳转,提升技术栈。内容知识点有Linux、Nginx、ZeroMQ、MySQL、Redis、线程池、MongoDB、ZK、Linux内核、CDN、P2P、epoll、Docker、TCP/IP、coroutine、DPDK等等。
点击完整视频链接:C/C++Linux服务器开发/后台架构师【零音学院】-学习视频教程-腾讯课堂
条件变量中的执行逻辑:
关键是要明白执行到int pthread _ cond _ wait(pthread _ cond _ t * restrict cond,pthread _ mutex _ t * restrict mutex)时会发生什么。其他的都比较好理解。在执行这个函数之前,需要获取互斥锁,判断是否满足条件,如果满足执行条件,继续向下执行,释放锁;如果判断不满足执行条件,则释放锁,线程在此被阻塞。等到其他线程通知满足执行条件,唤醒线程,再次锁死,向下执行后释放锁。(简而言之:解锁->阻塞等待->唤醒后锁定返回)
上面的示例可能很乏味,但下面的代码示例更简洁:
#include#include#include#include#include#include#include#defineNUM3pthread_cond_tcondv=PTHREAD_COND_INITIALIZER;pthread_mutex_tmlock=PTHREAD_MUTEX_INITIALIZER;voidproducer(void*arg){intn=NUM;while(n–){sleep(1);pthread_cond_signal(&condv);printf(“producerthreadsendnotifysignal.%d\t”,NUM-n);}}voidconsumer(void*arg){intn=0;while(1){pthread_cond_wait(&condv,&mlock);printf(“recvproducerthreadnotifysignal.%d\n”,++n);if(NUM==n){break;}}}intmain(){pthread_ttid1,tid2;pthread_create(&tid1,NULL,(void*)producer,NULL);pthread_create(&tid2,NULL,(void*)consumer,NULL);pthread_join(tid1,NULL);pthread_join(tid2,NULL);return0;}
运行结果:
producerthreadsendnotifysignal.1recvproducerthreadnotifysignal.1producerthreadsendnotifysignal.2recvproducerthreadnotifysignal.2producerthreadsendnotifysignal.3recvproducerthreadnotifysignal.3
[3]旗语
信号量适用于控制只支持有限数量用户的共享资源。用于将计数值保持在0和指定的最大值之间。当线程完成一次对信号量对象的等待时,计数值减一;当线程完成释放信号量对象一次时,计数值增加1。当计数值为0时,线程挂起并等待,直到计数值超过0。
主要功能如下:
#includeintsem_init(sem_t*sem,intpshared,unsignedintvalue);intsem_wait(sem_t*sem);intsem_trywait(sem_t*sem);intsem_post(sem_t*sem);intsem_destroy(sem_t*sem);
代码示例如下:
#include#include#include#include#include#include#include#include#defineNUM5intqueue[NUM];sem_tpsem,csem;voidproducer(void*arg){intpos=0;intnum,count=0;for(inti=0;i