• Linux多线程C++版(二) 线程创建 pthread_create()函数


    1.线程创建 pthread_create
    #include 
    int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(start_rtn)(void*),void *restrict arg)
    返回值:成功返回 0 否则返回错误编号
    //void* 标识通用类型
    
    • 1
    • 2
    • 3
    • 4
    • 参数

      • tidp:线程标识符指针
      • attr:线程属性指针
      • start_rtn:线程运行函数的起始地址
      • arg:传递给线程运行函数的参数
    • 创建线程从start_rtn函数的地址开始运行

    • 默认情况下不能保存新线程和调用线程的执行顺序,但是可以人工干预。

    此时代码pthread_create中的参数arg为 50单个参数

    #include
    #include
    #include
    #include
    //定义线程运行函数
    void* th_fn(void* arg) {
    	//void* arg 传过来的int类型的数值 要用需要强制转换成int
    	int distance = (int)arg;
    	for (int i = 1; i < distance; i++) {
    		printf("&lx run %d\n", pthread_self, i);
    		//int time = (int)(drand48() * 10000);//产生随机数 drand48只有在Linux下才有
    		Sleep(5);//阻塞5毫秒 
    	}
    	return (void*)0;
    }
    int main(void) {
    	
    	//用于接收线程是否创建成功的返回值
    	int err;
    	//定义线程标识符rabbit turtle
    	pthread_t rabbit, turtle;
    
    	//创建rabbit线程
    	if ((err = pthread_create(&rabbit, NULL, th_fn, (void*)50)) != 0) {
    		perror("pthread_create error");
    	}
    
    	//创建turtle线程
    	if ((err = pthread_create(&turtle, NULL, th_fn, (void*)50)) != 0) {
    		perror("pthread_create error");
    	}
    
    	//阻塞10秒  如果不阻塞,因为三个线程不知道谁先进行,可能会有主线程做完整个进程就结束了,剩余两个进程不会再走
    	//Sleep(10);
    
    	//后面会详细介绍
    	//pthread_join是主控线程调用的,表示自己会阻塞
    	//直到rabbit线程结束  主控线程方可运行
    	pthread_join(rabbit, NULL);
    	pthread_join(turtle, NULL);
    	//输出的是主控线程的ID
    	printf("control thread id:%lx\n", pthread_self());
    	printf("finished!\n");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    此时代码pthread_create中的参数arg为 一个结构体RaceArg

    #include
    #include
    #include
    #include
    //定义结构体
    typedef struct{
        char name[20];//姓名
        int time;//休眠时间
        int start;//开始地点
        int end;//结束地点
    }RaceArg;
    //定义线程运行函数
    void* th_fn(void* arg) {
    	//void* arg 传过来具体参数是结构体指针 要用需要强制转换成结构体
    	RaceArg *r = (RaceArg*)arg;
        //取值
        int i = r->start;
    	for (; i <= r->end; i++) {
    		printf("%s(%lx) running %d\n", r->name,pthread_self, i);
    		//int time = (int)(drand48() * 10000);//产生随机数 drand48只有在Linux下才有
    		Sleep(r->time);//阻塞5毫秒 
    	}
    	return (void*)0;
    }
    int main(void){
        
        //用于接收线程是否创建成功的返回值
    	int err;
        
    	//定义线程标识符rabbit turtle
    	pthread_t rabbit, turtle;
        
        //结构体赋值
        RaceArg r_a = {"rabbit",(int)(drand48() * 10000),20,50};
        RaceArg t_a = {"turtle",(int)(drand48() * 10000),10,60};
        
        //创建rabbit线程,并给与赋值
    	if ((err = pthread_create(&rabbit, NULL, th_fn, (void*)&r_a)) != 0) {
    		perror("pthread_create error");
    	}
    
    	//创建turtle线程,并给与赋值
    	if ((err = pthread_create(&turtle, NULL, th_fn, (void*)&r_t)) != 0) {
    		perror("pthread_create error");
    	}
        
        //阻塞主线程,等待rabbit和turtle线程结束
        pthread_join(rabbit, NULL);
    	pthread_join(turtle, NULL);
    	//输出的是主控线程的ID
    	printf("control thread id:%lx\n", pthread_self());
    	printf("finished!\n");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    注意:以上面代码为例,每个线程之间的局部变量互不影响如:int i或者指针 r都是每个线程自己数据不会相互影响,但是如果是全局变量,就是共享数据

    在这里插入图片描述

  • 相关阅读:
    01.shiro入门
    Spring 6 提前编译:AOT
    SpringBoot项目启动后访问网页显示“Please sign in“
    Docker容器之Consul部署
    2024年电商视频号夏令营(第四期)零基础带你玩转微信视频号
    C++11:异常和智能指针
    Node.js 零基础入门 Node.js 零基础入门第四天 4.5 前后端的身份认证
    vue3+ts,处理树形结构数据
    卫星影像如何插入到AutoCAD使用
    Maven使用安装
  • 原文地址:https://blog.csdn.net/kaszxc/article/details/127892059