【回眸】技术干货——Linux 内核 (十六) 之 多线程编程 上
前言
多线程编程的内容稍微有点多,分上下两篇博文。
进程和线程 区别
进程——资源分配的最小单位,线程——程序执行的最小单位
进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。
线程API
多线程开发在 Linux 平台上已经有成熟的 pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,线程操作又分线程的创建,退出,等待 3 种。互斥锁则包括 4 种操作,分别是创建,销毁,加锁和解锁。条件操作有 5 种操作:创建,销毁,触发,广播和等待。
1.创建线程
#include <pthread.h> int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg); // 返回:若成功返回0,否则返回错误编号
2.线程退出
#include <pthread.h> int pthread_exit(void *rval_ptr);
3.线程等待
#include <pthread.h> int pthread_join(pthread_t thread, void **rval_ptr); // 返回:若成功返回0,否则返回错误编号
4.线程脱离
#include <pthread.h> int pthread_detach(pthread_t thread); // 返回:若成功返回0,否则返回错误编号
5. 线程ID获取及比较
#include <pthread.h> pthread_t pthread_self(void); // 返回:调用线程的ID
#include <pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2); // 返回:若相等则返回非0值,否则返回0
6.创建及销毁互斥锁
#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); // 返回:若成功返回0,否则返回错误编号
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mutex) int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); // 返回:若成功返回0,否则返回错误编号
7.创建及销毁条件变量
#include <pthread.h> int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); int pthread_cond_destroy(pthread_cond_t cond); // 返回:若成功返回0,否则返回错误编号
8. 等待
#include <pthread.h> int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout); // 返回:若成功返回0,否则返回错误编号
9.触发
#include <pthread.h> int pthread_cond_signal(pthread_cond_t cond); int pthread_cond_broadcast(pthread_cond_t cond); // 返回:若成功返回0,否则返回错误编号
多线程编程
thread1.c(线程创建)
#include <stdio.h> #include <pthread.h> void *func1(void *arg){ printf("t1:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t1:param is %d\n",*((int *)arg)); } int main(){ int ret; int param =100; pthread_t t1; ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); while(1); return 0; }
thread2.c(等待和退出,传整数)
#include <stdio.h> #include <pthread.h> void *func1(void *arg){ static int ret = 10; printf("t1:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t1:param is %d\n",*((int *)arg)); pthread_exit((void *)&ret); } int main(){ int ret; int param =100; int *pret; pthread_t t1; ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); //while(1); pthread_join(t1,(void **)&pret); printf("main:t1 exit. ret = %d\n", *pret); return 0; }
thread3.c(等待和退出 传字符串)
#include <stdio.h> #include <pthread.h> void *func1(void *arg){ static char *p = "t1 pijiuya1 is runing.\n"; printf("t1:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t1:param is %d\n",*((int *)arg)); pthread_exit((void *)p);//退出 } int main(){ int ret; int param =100; char *pret = NULL; pthread_t t1; ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); //while(1); pthread_join(t1,(void **)&pret);//等待 printf("main:t1 exit. ret = %s\n", pret); return 0; }
thread4.c(创建2个)
#include <stdio.h> #include <pthread.h> void *func1(void *arg){ static int ret = 10; printf("t1:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t1:param is %d\n",*((int *)arg)); pthread_exit((void *)&ret); } int main(){ int ret; int param =100; int *pret; pthread_t t1; ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); //while(1); pthread_join(t1,(void **)&pret); printf("main:t1 exit. ret = %d\n", *pret); return 0; }
thread5.c(创建2个且打印顺序发现多线程共享同一段内存【顺序没有重复】)
#include <stdio.h> #include <pthread.h> #include <unistd.h> int g_data = 0; void *func1(void *arg){ printf("t1:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t1:param is %d\n",*((int *)arg)); while(1){ printf("t1:%d\n",g_data++); sleep(1); }; } void *func2(void *arg){ printf("t2:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t2:param is %d\n",*((int *)arg)); while(1){ printf("t2:%d\n",g_data++); sleep(1); }; } int main(){ int ret; int param =100; pthread_t t1; pthread_t t2; ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); ret = pthread_create(&t2,NULL,func2,(void *)¶m); if(ret == 0){ printf("main:Create t2 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); while(1){ printf("main:%d\n",g_data++); sleep(1); }; pthread_join(t1,NULL);//等待 pthread_join(t2,NULL);//等待 return 0; }
抢占资源是随机的,每次运行的结果不尽相同。
thread6.c(创建3个线程并且加锁,让t1优先运行且不被t2 t3 打断,t1 释放锁后,t3和t2竞争资源)
#include <stdio.h> #include <pthread.h> #include <unistd.h> pthread_mutex_t mutex; pthread_attr_t attr; void *func1(void *arg){ int i ; pthread_mutex_lock(&mutex);//保证t1优先 for(i = 0;i<5;i++){ printf("t1:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t1:param is %d\n",*((int *)arg)); } pthread_mutex_unlock(&mutex); } void *func2(void *arg){ pthread_mutex_lock(&mutex); printf("t2:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t2:param is %d\n",*((int *)arg)); pthread_mutex_unlock(&mutex); } void *func3(void *arg){ pthread_mutex_lock(&mutex); printf("t3:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t3:param is %d\n",*((int *)arg)); pthread_mutex_unlock(&mutex); } int main(){ int ret; int param =100; pthread_t t1; pthread_t t2; pthread_t t3; pthread_mutex_init(&mutex,NULL); ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } ret = pthread_create(&t2,NULL,func2,(void *)¶m); if(ret == 0){ printf("main:Create t2 sucess.\n"); } ret = pthread_create(&t3,NULL,func3,(void *)¶m); if(ret == 0){ printf("main:Create t3 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); pthread_join(t1,NULL);//等待 pthread_join(t2,NULL);//等待 pthread_join(t3,NULL);//等待 pthread_attr_destroy(&attr); return 0; }
thread7.c(fun1先运行到10退出锁,func2后运行不退出)
#include <stdio.h> #include <pthread.h> #include <unistd.h> pthread_mutex_t mutex; pthread_attr_t attr; int g_data = 0; void *func1(void *arg){ pthread_mutex_lock(&mutex);//保证t1优先 while(1){ printf("t1:%d\n",g_data++); sleep(1); if (g_data == 10){ pthread_mutex_unlock(&mutex); pthread_exit(NULL); } } } void *func2(void *arg){ printf("t2:%ld thread is created.\n",(unsigned long)pthread_self()); printf("t2:param is %d\n",*((int *)arg)); while(1){ pthread_mutex_lock(&mutex); printf("t2:%d\n",g_data); g_data++; pthread_mutex_unlock(&mutex); sleep(1); } } int main(){ int ret; int param =100; pthread_t t1; pthread_t t2; pthread_mutex_init(&mutex,NULL); ret = pthread_create(&t1,NULL,func1,(void *)¶m); if(ret == 0){ printf("main:Create t1 sucess.\n"); } ret = pthread_create(&t2,NULL,func2,(void *)¶m); if(ret == 0){ printf("main:Create t2 sucess.\n"); } printf("mainID:%ld .\n",(unsigned long)pthread_self()); printf("main:g_data = %d.\n",g_data); pthread_join(t1,NULL);//等待 pthread_join(t2,NULL);//等待 pthread_attr_destroy(&attr); return 0; }
后记碎碎念
Linux内核是一个系列,可以点击专栏查看同系列的其他文章,希望能帮到屏幕前的每一位应届生往届生,该博文最初发表在CSDN上。
这个多线程的内容在Java里代码很少,回顾了linux这里的互斥锁,感受更加不一样,比当时更加理解了互斥锁的问题。
#校招求职有谈薪空间吗##找工作前vs找工作后的心路变化##租房前辈的忠告##职场中你干过哪些“蠢”事##26届秋招投递记录#应届生必学实用物联网技术 文章被收录于专栏
本专栏助应届生从物联网小白成长为企业争抢的技术人才,聚焦三大核心技术:传感器应用(环境监测)、嵌入式开发(STM32/Arduino)、通信协议(LoRa/NB-IoT/MQTT),配合10+实战项目(如智能温湿度监控系统)积累项目经验。覆盖智能硬件、工业物联网、智能家居领域岗位需求,解析企业招聘技术重点与面试题,帮电子、计算机、自动化等专业学生构建知识体系,提前锁定名企Offer!