多线程编程(c++多线程编程)

35小吃技术网 推荐阅读 2022年12月04日18时32分34秒 243 0

多线程编程(c++多线程编程)

多线程编程可以说是每个程序员的基本功,也是开发中的难点之一。以Linux C为例,介绍了线程的创建和几种常见的线程同步方式。最后对多线程编程进行了总结和思考,并给出了代码示例。

首先,创建一个线程

多线程编程的第一步是创建线程。创建一个线程实际上增加了一个控制进程,使得同一个进程中的多个控制进程并发或并行执行。

创建线程函数。其他功能不在此列。可以参考pthread.h

多线程编程(c++多线程编程)-第1张图片

#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);

代码示例如下:

多线程编程(c++多线程编程)-第2张图片

#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