c 线程

本文详细介绍了Linux中线程与进程的区别,强调了线程在Linux内核中被视为轻量级进程,二者共享大部分资源如.text、.bss、.data等,但拥有独立的栈。通过实例展示了如何创建线程、设置线程分离以及线程通信。同时,讨论了线程的线程ID(LWP)与线程号的概念,以及如何观察线程的LWP号。最后,提到了线程的管理和终止,包括pthread_cancel函数的使用注意事项。
摘要由CSDN通过智能技术生成

创建线程以后,地址空间没有变化,进程退化成线程. 创建的子线程和主线程公用一份地址空间.
在linux 下 线程就是轻量级进程. 对于linux内核不区分线程和进程
在这里插入图片描述
主线程和子线程
共享的部分

  • .text
  • .bass
  • .data
  • 堆 动态库加载区 环境变量 命令行参数
  • 可以通过 全局变量 或 堆进行通信

不共享的部分

观察指定线程的LWP号

线程号和线程id的区别

  • 线程号LWP是给内核看的.
  • 线程id是给程序员看的
    查看方式
  • 找到程序的进程id
  • ps -Lf pid

多进程和多线程的区别

多进程共享的资源

  • 代码
  • 文件描述符
  • 内存映射区 mmap

进程和线程共享的资源

  • 全局变量
  • 线程节省资源

DEMO

gcc d.c -lpthread
pthread_join 和 pthread_exit 参数接受一个指针, 是一个传出参数.可得到退出状态

int pthread_create(pthread_t *thread, 	//线程ID 无符号长整形
const pthread_attr_t *attr,	//线程属性 .NULL,可以设置线程分离
void *(*start_routine) (void *),	//线程处理函数 
void *arg)	//线程处理函数参数
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <pthread.h>

void* myfunc(void* arg){
    //打印子线程id
    printf("child thread id %d\n", pthread_self());
    for(int i=0; i<5;i++){
        printf("child i=%lu\n", i);
        sleep(1);
    }
    return NULL;
}

int main(){

    pthread_t ptid;
    int ret = pthread_create(&ptid, NULL, myfunc, NULL);
    if (ret != 0){
        printf("pthread err %d\n", ret);

    }
    printf("parent thread id %lu\n", pthread_self());

    for (int i = 0; i < 10; i++)
    {
        printf("father i=%d\n", i);
    }
    //如果不加下面这句话. 主线程直接退出,子线程也会退出.
    pthread_exit(NULL);		//加上这句话, 主线程退出,子线程继续执行.

    return 0;
}

线程分离

  • int pthread_detach(pthread_t thread); 或者创建线程的时候 设置线程属性
  • 调用该函数后,不再需要pthread_join
  • 线程会自己回收自己的tcb
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>


void *thrd_func(void *arg)
{	
	sleep(1);//防止分离的线程在pthread_create返回tid之前结束,导致tid为失败值而认为创建线程失败
    pthread_exit((void *)77);
}

int main(void)
{
    pthread_t tid;
    int ret;
    pthread_attr_t attr;
	
	//1 
    ret = pthread_attr_init(&attr);
    if (ret != 0) {
        fprintf(stderr, "pthread_init error:%s\n", strerror(ret));
        exit(1);
    }
	
	//2 设置线程分离
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	
	//3 这一步注意:若pthread_create创建分离的线程后,并且在返回tid之前结束,tid可能是一个失败值。所以可以使分离的线程睡眠一下。
    ret = pthread_create(&tid, &attr, thrd_func, NULL);
    if (ret != 0) {
        fprintf(stderr, "pthread_create error:%s\n", strerror(ret));
        exit(1);
    }
	
	/*
	//这一步只是验证是否成功属性分离,若成功则回收失败
    ret = pthread_join(tid, NULL);
    if (ret != 0) {
        fprintf(stderr, "pthread_join error:%s\n", strerror(ret));
        exit(1);
    }
	*/
    //释放资源
    pthread_attr_destroy(&attr);

    pthread_exit((void *)1);
}

杀死子线程

  • pthread_cancel
  • 使用注意事项
  • 在杀死的子线程对应的处理函数的内部,必须做过一次系统调用.
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北京时光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值