Linux——线程1 | 用C创建线程、循环创建多个子线程

一、线程基础

进程:有独立的进程地址空间,有独立的pcb
线程:有独立的pcb,没有独立的进程地址空间
因此进程线程最本质的区别就是:是否共享地址空间
在Linux下线程是最小的执行单位;进程是最小的分配资源单位,可看成只有一个线程的进程

看进程下的线程号:ps -Lf 进程ID LWP—>CPU执行的最小单位

线程共享和非共享

  • 线程共享资源:
    1,文件描述符表
    2,每种信号的处理方式
    3,当前工作目录
    4,用户ID和组ID
    5,内存地址空间(./text/.data/.bss/heap/共享库)

  • 线程非共享资源
    1,线程id
    2,处理器线程和栈指针
    3,独立的栈空间(用户空间栈
    4,errno变量
    5,信号屏蔽字
    6,调度优先级

gdb不支持线程,线程对信号支持也不太好
但线程可以提高程序并发性,且开销小,数据通信共享数据都方便

二、创建线程

线程控制原语

两个概念:
线程ID和线程号(LWP)
线程ID是在进程中用来表示线程身份的;线程号LWP是标识线程身份给cpu用的,用来划分时间轮线,决定每个程序的执行时间
1,pthread_create 创建一个新线程
在这里插入图片描述第一个参数:传出新创建线程的传出ID;
第二个参数:描述线程的属性:通过调整线程属性可以调整线程各种状态,比如说线程分离,线程优先级,线程所占空间大小等,但是要是没有特殊要求就可以只传一个NULL空值;
第三个参数:一个回调参数
第四个参数:泛型指针,就是第三个参数所需要的参数,不需要参数就传入NULL
成功返回0,失败返回错误号

2,pthread_self 获取线程ID
pthread_t pthread_self(void);注意线程ID是pthread_t类型的,且线程ID是进程内部的识别标识,两个进程间的线程ID是允许相同的

在这里插入图片描述

例子👇

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>

void sys_err(const char*str)
{
	perror(str);
	exit(1);
}
void *tfn(void *argc)
{
	printf("thread: pid = %d, tid = %lu\n", getpid(), pthread_self());
	return NULL;
}

int main(int argc, char *argv[])
{
	pthread_t tid;
	int ret = pthread_create(&tid, NULL, tfn, NULL);
	if(ret != 0)
	{
		perror("pthread_create error");
	}
	printf("main: pid = %d, tid = %lu\n",getpid(),pthread_self());
	sleep(1);
	return 0;
}

在这里插入图片描述
可以看到主线程和子线程的进程id都是一样的,但是线程id是不同的

三、循环创建多个子线程

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>

void sys_err(const char*str)
{
	perror(str);
	exit(1);
}

void *tfn(void *arg)
{
	int i = (int)arg;
	sleep(i);
	printf("I am %dth thread: pid = %d, tid = %lu\n",i+1, getpid(), pthread_self());
	return NULL;
}

int main(int argc, char *argv[])
{
	int i;
	int ret;//接收线程创建的返回值,用于确认创建是否成功
	pthread_t tid;//第一个参数,传出参数,表示新创建线程的ID
	for(i = 0; i<5; ++i)
	{
		ret = pthread_create(&tid,NULL,tfn,(void*)i)//往回调函数中传参数i,表示是第几个参数
		if(ret != 0)
		{
			sys_err("pthread_create error");
		}
	}
	sleep(i);//如果没有这一行很可能子线程回调函数还没来得及整个进程就没了
	printf("main:  pid = %d, tid = %lu\n",getpid(), pthread_self());
	return 0;
}

在这里插入图片描述
还是一样的进程i,不同的线程id

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值