Linux环境:C编程之多线程

本文详细介绍了Linux环境中C语言实现多线程的编程技术,包括线程的创建与退出、线程的终止与清理、线程互斥与同步、线程安全性等内容。通过示例程序演示了线程的创建、线程的终止清理、线程同步的实现以及线程安全性的概念和不安全进程的四种情况。
摘要由CSDN通过智能技术生成

线程的创建与退出

线程创建函数

函数原型
int pthread_create(pthread_t* thread, pthread_attr_t * attr, void *(*start_routine)(void *), void * arg);

返回值与参数

  • 返回值:成功,则返回 0;失败,则返回对应错误码。
  • 参数 thread 是传出参数,保存新线程的标识;
  • 参数 attr 是一个结构体指针,结构中的元素分别指定新线程的运行属性,attr 可以用pthread_attr_init 等函数设置各成员的值,但通常传入为 NULL 即可
  • 参数 start_routine 是一个函数指针,指向新线程的入口点函数,线程入口点函数带有一个 void *的参数由 pthread_create 的第 4 个参数传入;
  • 参数 arg 用于传递给第 3 个参数指向的入口点函数的参数,可以为 NULL,表示不传递。
线程退出
void pthread_exit(void *retval);

函数 pthread_exit 用在线程函数中表示线程的退出。其参数可以被其它线程用 pthread_join 函数捕获。

int pthread_join(pthread_t th, void **thread_return);

用于回收线程返回值,相当于进程中的waitwaitpid
th指定要回收的线程,thread_return 是一个传出参数,接收线程函数的返回值。

示例程序

创建一个子线程,传入数值1,在子线程中能够获取并打印,子线程退出,返回数值2,主线程通过pthread_join获取等待子线程结束并获取子线程的退出值并打印

#include <fun.h>

void* thread1(void * val)
{
   
    printf("线程创建成功,传入参数:%d\n",(int)val);
    pthread_exit((void *)2);
}
int main(int args,char *argv[])
{
   
    pthread_t p=0;
    int ret =  pthread_create(&p,NULL,thread1,(void *)1);
    THREAD_CHECK(ret,"pthread_create")
    pthread_join( p,(void **)&ret);

    printf("父进程回收:%d\n",ret);
    
    return 0;
}

执行效果:
在这里插入图片描述

线程的终止与清理

线程终止
  • int pthread_cancel(pthread_t thread);//向thread线程发送cancel信号
  • 通过其他线程向目标线程发送cancel信号可以使目标线程按照设计好的方式终止。
  • 目标线程收到信号后或者忽略、或者立即终止、或者继续运行至 cancelation-point(取消点)后结束。
  • 取消点一般是能引起阻塞的系统调用,在设置取消点时应在系统调用前后加上pthread_testcancel()调用来符合到 POSIX 标准。
线程清理

线程运行过程中常常会意外终止,无法正常释放掉自己所占用的资源从而对其他线程造成影响,或者造成系统资源浪费,所以需要引入线程清理机制。

POSIX 线程 API 提供了以下函数对用于在进程结束时自动释放资源:

void pthread_cleanup_push(void (*routine) (void *), void *arg)/void pthread_cleanup_pop(int execute)

  • 用法:在线程中成对出现,对两个函数段之间的代码段进行保护,如果线程运行在清理函数中间的代码段时终止,则执行定义好的清理函数。如果有多个清理函数对,则遵循先入后出的规则,类似括号匹配规则
  • pthread_cleanup_push函数的参数为一个函数指针指向清理函数,和传给该清理函数的参数
  • pthread_cleanup_pop函数从参数为0表示执行到该函数时不执行清理函数,参数非0则执行清理函数。该参数不影响线程在pthread_cleanup_pop之前退出时的自动清理。
示例程序

创建一个子线程,子线程申请内存,通过清理函数进行free,子线程停留在read标准输入,主线程cancel子线程,子线程能够通过清理函数free对应的malloc的内存

#include <fun.h>
void freept(void * p)
{
   
    printf("开始清理!\n");
    free(
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值