【回眸】技术干货——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!

全部评论

相关推荐

威猛的香菇在秋招:感觉假的…测开怎么可能才13k
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务