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

线程的同步

线程的相关编程

     1. 线程的创建: pthread_create()
pthread_self():获取当前线程的ID号

#include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
功能:创建一个新的线程
参数:
thread : 保存线程ID的变量地址
attr:线程属性的对象地址
NULL : 按照默认属性创建
start_routine:函数的指针:指向线程启动后要执行的任务(线程任务函数)
arg:为线程任务函数传递的参数
返回值:
成功:0
失败:非0

该代码是一个进程的创建

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>//次线程
void *task(void *arg)
{printf("I am thread : tid = %ld\n", pthread_self());
}int main(int argc, const char *argv[])
{//主进程、主线程pthread_t tid;int ret = pthread_create(&tid, NULL, task, NULL);if (ret !=0){printf("pthread_create error\n");return -1;}while (1){}return 0;
}
#include <stdio.h>
#include <pthread.h>struct stu
{int id;char name[32];
};void *task(void *arg)
{struct stu *ps = (struct stu *)arg;//进行强转操作//int num = *((int *)arg); printf("tid = %lx, id= %d, name = %s\n", pthread_self(), ps->id, ps->name);return NULL;
}
int main(int argc, const char *argv[])
{pthread_t tid;int num = 100;struct stu s = {1, "zhangsna"};int ret = pthread_create(&tid, NULL, task, &s);if (ret != 0){printf("pthread_create error\n");return -1;}printf("tid1 = %lx\n", tid);while (1){}return 0;
}

int pthread_join(pthread_t thread, void **retval);
功能:阻塞等待回收线程资源空间
参数:
thread:要回收的线程ID
retval:用来保存线程退出时传递的参数
NULL: 不接收传递的参数
返回值:
成功:0
失败:-1

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>//次线程
void *task(void *arg)
{int i = 0;while (1){if (++i == 10){char str[] = {"thread over!"};//	return "hello";pthread_exit(NULL); // return NULL;}printf("I am thread : tid = %ld\n", pthread_self());sleep(1);}printf("hello world\n");return NULL;
}int main(int argc, const char *argv[])
{//主进程、主线程pthread_t tid;int ret = pthread_create(&tid, NULL, task, NULL);if (ret !=0){printf("pthread_create error\n");return -1;}//void *retval;pthread_join(tid, NULL);//printf("retval -> %s\n", (char *)retval);return 0;
}

线程回收策略:

1. 分离属性的线程:不需要回收,由操作系统回收。(没有空闲的线程可帮忙回收时)
2. 非分离属性的线程:pthread_join()阻塞回收

线程属性:

1. 分离属性:不需要被其他线程回收的线程称为分离属性得到线程,将来会被操作系统所回收
int pthread_detach(pthread_t thread);
功能:将线程设置成分离属性的线程
2. 非分离属性:可以被其他线程回收或者结束的线程,称为非分离属性的线程默认属性:非分离属性)

这种设置线程为分离属性,到最后凋亡后会由操作系统回收。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>//次线程
void *task(void *arg)
{
//	printf("I am thread : tid = %ld\n", pthread_self());
}int main(int argc, const char *argv[])
{//主进程、主线程pthread_t tid;int i = 0;	while (1){int ret = pthread_create(&tid, NULL, task, NULL);if (ret !=0){printf("pthread_create error\n");return -1;}pthread_detach(tid);i++;printf("i = %d\n", i);}return 0;
}

线程间通信:

全局变量通信:

线程间互斥机制:

临界资源:多个线程可以同时访问的资源称为临界资源:比如,全局变量、共享内存区域等
多个线程在访问临界资源时,存在资源竞争问题。

如何解决资源竞争问题:
互斥机制:多个线程访问临界资源时,具有排他性访问的机制(一次只允许一个线程对该临界资源进行访问)。
互斥锁--》解决资源竞争问题。

#include <stdio.h>
#include <pthread.h>int num_g = 100;void *task1(void *arg)
{num_g = 1000;while (1){printf("th1 -> num = %d\n", num_g);sleep(1);}
}void *task2(void *arg)
{while (1){printf("th2 -> num = %d\n", num_g);sleep(1);}
}int main(int argc, const char *argv[])
{pthread_t tid[2];pthread_create(&tid[0], NULL, task1, NULL);pthread_create(&tid[1], NULL, task2, NULL);pthread_join(tid[0], NULL);pthread_join(tid[1], NULL);return 0;
}

实现步骤:
1. 创建互斥锁:pthread_mutex_t
2. 初始化互斥锁:pthread_mutex_init();
3. 加锁:int pthread_mutex_lock(pthread_mutex_t *mutex);
4. 解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);
5. 销毁锁:int pthread_mutex_destroy(pthread_mutex_t *mutex);

 int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
功能:初始化互斥锁
参数:
mutex:锁对象地址
attr:锁的属性 (NULL:默认属性)
返回值:
成功:0
失败:-1

#include <stdio.h>
#include <pthread.h>int num_g = 0;
pthread_mutex_t mutex;void *task1(void *arg)
{for (int i = 0; i < 100000; i++){pthread_mutex_lock(&mutex);num_g = num_g+1;printf("num_g = %d\n", num_g);pthread_mutex_unlock(&mutex);}
}void *task2(void *arg)
{for (int i = 0; i < 100000; i++){pthread_mutex_lock(&mutex);num_g = num_g+1;printf("num_g = %d\n", num_g);pthread_mutex_unlock(&mutex);}}int main(int argc, const char *argv[])
{pthread_t tid[2];pthread_mutex_init(&mutex, NULL);pthread_create(&tid[0], NULL, task1, NULL);pthread_create(&tid[1], NULL, task2, NULL);pthread_join(tid[0], NULL);pthread_join(tid[1], NULL);pthread_mutex_destroy(&mutex);return 0;
}

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

相关文章:

  • 魔改chromium源码——解除 iframe 的同源策略
  • Go语言实战案例-使用ORM框架 GORM 入门
  • 0️⃣基础 认识Python操作文件夹(初学者)
  • E2B是一个开源基础设施,允许您在云中安全隔离的沙盒中运行AI生成的代码和e2b.dev网站
  • 基因编辑预测工具:inDelphi与Pythia
  • Linux学习记录
  • 图解简单选择排序C语言实现
  • 01数据结构-插入排序
  • 一文读懂[特殊字符] LlamaFactory 中 Loss 曲线图
  • 防火墙带宽管理
  • 使用 Python 的 `cProfile` 分析函数执行时间
  • AUTOSAR进阶图解==>AUTOSAR_SWS_EthernetStateManager
  • 【PHP】Hyperf:接入 Nacos
  • 今日Java高频难点面试题推荐(2025年8月17日)
  • Python数据类型转换详解:从基础到实践
  • 【Kubernetes系列】Kubernetes中的resources
  • Matlab数字信号处理——ECG心电信号处理心率计算
  • FreeRTOS 中的守护任务(Daemon Task)
  • 第七十七章:多模态推理与生成——开启AI“从无到有”的时代!
  • 【C++知识杂记2】free和delete区别
  • c++--文件头注释/doxygen
  • Linux应用软件编程---多任务(线程)(线程创建、消亡、回收、属性、与进程的区别、线程间通信、函数指针)
  • 工作八年记
  • 官方正版在线安装office 365安装工具
  • 数组的三种主要声明方式
  • 大模型对齐算法(二): TDPO(Token-level Direct Preference Optimization)
  • Android中使用Compose实现各种样式Dialog
  • tcp会无限次重传吗
  • Eclipse Tomcat Configuration
  • Portkey-AI gateway 的一次“假压缩头”翻车的完整排障记:由 httpx 解压异常引发的根因分析