当前位置: 首页 > news >正文

【回眸】Linux 内核 (十五) 之 多线程编程 上

前言

进程和线程 区别

线程API

1.创建线程

2.线程退出 

3.线程等待

4.线程脱离

5. 线程ID获取及比较 

6.创建及销毁互斥锁

7.创建及销毁条件变量

 8. 等待

9.触发

多线程编程 

后记

前言

高产的几天。

进程和线程 区别

进程——资源分配的最小单位,线程——程序执行的最小单位

进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。

线程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 *)&param);
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 *)&param);
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 *)&param);
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 *)&param);
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 *)&param);
if(ret == 0){
printf("main:Create t1 sucess.\n");
}
printf("mainID:%ld .\n",(unsigned long)pthread_self());
ret = pthread_create(&t2,NULL,func2,(void *)&param);
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 *)&param);
if(ret == 0){
printf("main:Create t1 sucess.\n");
}
ret = pthread_create(&t2,NULL,func2,(void *)&param);
if(ret == 0){
printf("main:Create t2 sucess.\n");
}
ret = pthread_create(&t3,NULL,func3,(void *)&param);
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 *)&param);
if(ret == 0){
printf("main:Create t1 sucess.\n");
}
ret = pthread_create(&t2,NULL,func2,(void *)&param);
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;
}

后记

内容实在是有点多,故而分两篇博文。这个多线程的内容在Java里代码很少,回顾了linux这里的互斥锁,感受更加不一样,比当时更加理解了互斥锁的问题。

http://www.dtcms.com/a/122222.html

相关文章:

  • 4月9日笔记
  • 2021-10-26 C++繁忙通信兵
  • Java 设计模式:原型模式详解
  • 使用雪花算法生成分布式唯一ID
  • Android 回答视频边播放边下载的问题
  • GMSL Strapping Pins CFG0/CFG1 应用
  • 【力扣刷题实战】外观数列
  • ragflow开启https访问:浏览器将自签证书添加到受信任的根证书颁发机构 ,当证书过期,还需要添加吗?
  • 第一部分——Docker篇 第六章 容器监控
  • vulnhub:sunset decoy
  • 洛谷普及B3691 [语言月赛202212] 狠狠地切割(Easy Version)
  • 优化 Web 性能:移除未使用的 CSS 规则(Unused CSS Rules)
  • The packaging for this project did not assign a file to the build artifact
  • 02.使用cline(VSCode插件)、continue(IDEA插件)、cherry-studio玩转MCP
  • Android里面开子线程的方法
  • OpenHarmony子系统开发 - 调测工具(二)
  • 柑橘病虫害图像分类数据集OrangeFruitDataset-8600
  • Python: 实现数据可视化分析系统
  • Coze平台 发布AI测试Agent的完整实现方案
  • redis_exporter服务安装并启动
  • STL-list链表
  • mac 苍穹外卖 后端初始 SkyApplication 报错
  • HTTP:一.概述
  • 【Leetcode-Hot100】移动零
  • 净室软件工程:以数学为基石的高可靠性软件开发之道
  • 数学建模--在新能源汽车研发测试中的革命性应用
  • 最小覆盖子串 -- 滑动窗口
  • MMO 架构梳理
  • 分布式ID生成器设计详解
  • 直流有刷电机与H桥驱动