Linux线程笔记

进程和线程

  • 进程:一个正在执行的程序,是资源分配的最小单位
  • 线程:程序执行的最小单位,系统独立调度和分配CPU的基本单位,是进程中的一个实体,一个进程具有多个线程,线程共享进程中的所有资源,每个线程本身包含一点必不可少的资源
    在这里插入图片描述

并发,并行,同步,异步

|并发| 并行 |同步|异步|
|--|--|--|--|
| 看起来同时发生(单核) | 多条指令多个处理器同时执行 |防止同时发生的一种机制|任何两个彼此独立的操作是异步的,表明事件独立的发生|

创建线程(注意编译的时候需要 -lpthread )

//线程创建函数的四个参数
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
/*
1. *thread :线程号,线程创建成功之后会更新线程号
2. *attr: 属性,默认是NULL
3. 线程回调函数
4. 线程回调函数的参数,这里设置线程名
5. 返回值用来判断进程有没有创建成功
*/

//获取线程ID号码
//采用pthread_self() 可以获取到线程ID

#include "apue.h"//此头文件可能要下载
#include "pthread.h"

void print_id(char *s){//打印进程ID和线程ID
	pid_t pid; 
	pthread_t tid;
	pid = getpid();//获取进程ID号
	tid = pthread_self();//获取线程ID号
	printf("%s pid is %u ,tid is 0x%lx \n",s,pid,tid);

}

void* thread_fun(void *arg){ //线程函数
	print_id(arg);
	return(void*)0;
}

int main(){
	pthread_t ntid; 
	int err;
	err = pthread_create( &ntid, NULL,thread_fun,"newthread"); //调用线程创建函数
	if(err!=0){//线程创建失败
		printf("create fail\n");
		return 0;
	}
	print_id("main thread :");
	sleep(2);
	 return 0;

}

线程的几种状态

状态含义备注
就绪线程能够运行,但是在等待可用的处理器线程刚刚创建的时候就处于就绪状态,当被解除阻塞状态后也会处于就绪状态,当一个运行的线程被抢占的时候,立即又回到就绪状态
运行线程正在运行,在多核系统中,可能有多个线程在运行
阻塞线程在等待处理器以外的其他条件线程会在以下情况发生阻塞:试图加锁一个已经被锁住的互斥量,等待某个条件变量,调用singwait等待尚未发生的信号,执行无法完成的IO信号,由于内存页错误
终止线程从启动函数中返回,或者调用pthread_exit函数,或者被取消线程通常在启动函数中返回来中止自己,或者调用pthread_exit退出,或者取消线程

在这里插入图片描述

主线程

  • 当C程序运行的时候,首先运行main函数,这个特殊的执行流被称为初始线程或者主线程,可以在初始线程中做任何普通线程可以做的事情

主线程示例代码

#include "apue.h"
#include "pthread.h"

typedef struct{
	int age;
	char name[20];

}Student ;

Student student;

void* thread_fun(void* stu ){//线程函数:打印学生的年龄和名字
	printf("age is %d,name is %s\n",student.age,student.name);
	return (void*)0;
}

int main(int argc ,char* argv[]){// 主函数
	pthread_t tid;
	int err;
	student.age =20;//写入年龄
	memcpy(student.name,"zhangsan",20); //字符串拷贝
	err=pthread_create(&tid,NULL,thread_fun,(void*)(&student));//创建线程,参数是结构体的地址
	if(err!=0){
		printf("create a new thread failed\n");
		return 0;
	}
	int i ;
	for(i=0;i<argc;i++){
		printf("main thread arg is %s\n",argv[i]);//传递的参数
	}
	sleep(1);
	return 0;
}


线程退出代码

#include "apue.h"
#include "pthread.h"

void* thread_fun(void *arg){ //判断输入参数
	if(strcmp("1",(char*)arg)==0){
		printf("new thread return!\n ");
		return (void*)1;
	}
	if(strcmp("2",(char*)arg)==0){
		printf("new thread pthread_exit!\n ");
		pthread_exit((void*)2);
	}
	if(strcmp("3",(char*)arg)==0){
		printf("new thread exit!\n ");
		exit(3);
	}
}

int main(int argc ,char *argv[]){
	int err;
	pthread_t tid;
	err = pthread_create(&tid, NULL , thread_fun,(void*)argv[1]);
	if(err!=0){
		printf("create new thread failed\n");
		return 0;
	}
	sleep(1);
	printf("main thread \n");
	return 0;



}

主线程和普通线程

区别主线程普通线程
退出主线程的特殊性在于,在main函数返回的时候,会导致进程结束,进程内的所有线程也会结束,可以在主线程中调用pthread_exit函数,这样进程就会等待所有线程结束的时候才会结束线程结束可以:1. 从启动例程中返回,返回值是线程的退出码,2线程可以被同一个进程中的其他线程取消,3. 线程调用pthread_exit(void* rval)函数,*rval是退出码
接收参数主线程接收参数的方式是argcargv普通的线程只有一个void*
运行堆栈绝大多数情况下主线程在默认堆栈上运行,这个堆栈可以增长到足够的高度而普通线程的堆栈是受限制的,一旦溢出就会发生错误
创建主线程随着进程的创建而创建其他线程可以调用函数来创建(主要调用pthread_create
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值