linux学习-线程简介

线程概念
典型的linux系统下面,一个进程看成只有一个线程:一个进程在某一时刻只能做一件事情。而加入了多个控制线程之后,在某一时刻我们就可以做不止一件事情。
每个线程也有一个线程ID,用pthread_t数据类型来表示。可以调用函数pthread_self来获得自身的线程ID。

#include<pthread.h>
pthread_t  pthread_self(void);
                                             返回值:返回自身的id

线程的创建
新增的线程可以通过调用函数pthread_create来创建

#include<pthread.h>
int pthread_create(pthread_t *restrict tidp,const thread_attr_t *restrict attr,void *(*start_rtn)(void *),void *reatrict arg);
                返回值:若成功返回0,否则返回错误编号

参数tidp:新创建的线程ID会被设置成tidp指向的内存单元
参数arrt:用于定制各种不同的线程属性,NULL表示默认属性
参数start_rtn:新创建的线程从函数start_rtn的地址开始运行
参数arg:作为参数传入函数start_rtn,如果需要传递的参数在一个以上,需要构建结构体,然后把结构体地址作为参数传给函数。

一个创建线程的实例

#include<stdio.h>
#include<pthread.h>

void *thr_fn(void *arg)                                                //线程执行的函数
{
	printf("hello\n");
	return((void *)0);
}

int main()
{
pthread_t tid;
pthread_create(&tid,NULL,thr_fn,NULL);                    //创建线程
printf("ok\n");
sleep(2);                                                //主线程挂起,否则可能导致进程结束,新进程不运行
return 0;
}

线程的终止
在不终止整个进程的情况下,单个线程可以通过3种方式退出
1)线程可以简单的从启动例程返回
2)线程可以被同一进程中的其他线程取消
3)线程调用pthread_exit

#include<pthread.h>
int pthread_exit(void *rval_ptr);

参数rval_ptr:是一个无类型指针,与传给启动例程的单个参数相似。如果线程简单地从它的启动例程返回,rval_ptr就包含返回码,如果线程被取消,由rval_ptr指定的内存单元就设置为PTHREAD_CANCELED。
进程中的其他线程可以调用函数pthread_join来访问这个指针。当一个线程通过函数pthread_exit退出或简单的返回,进程中其他线程可以通过pthread_join函数来获得该线程的退出状态 。

#include<pthread.h>
int pthread_join(pthread_t thread,void **rval_ptr);
返回值:成功返回0,出错返回错误编码

线程可以通过调用函数pthread_cancel来请求取消同一进程中的其他线程。

#include<pthread.h>
int pthread_cancel(pthread_t tid);
                                      返回值:成功返回0,失败返回错误编码

不过需要注意的是,这个函数只是一个请求,并不等待线程终止。

线程可以安排它退出时需要调用的函数,这样的函数被称为线程清理函数

#include<pthread.h>
void pthread_cleanup_push(void(*rtn)(void *),void *arg);
void pthread_cleanup_pop(int execute);

当线程执行以下动作时,调用线程清理函数rtn
1)调用函数pthread_exit,
2) 响应取消请求时,
3) 用非零execute参数调用pthread_cleanup_pop时。

#include<stdio.h>
#include<pthread.h>
void cleanup(void *arg)                 //线程清理函数
{
	printf("clean up\n")
}

void *thr_fn(void *arg)                  //线程启动函数              
{
    printf("thread start\n");
    pthread_cleanup_push(cleanup,"hello");
    printf("thread push complete\n");
    if(arg)
    	pthread_exit((void *)1);
    pthread_cleanup_pop(0);             //删除调用建立的清理程序
    pthread_exit((void *)1);
 }

int main()
{
void *tret;
pthread_t tid;
pthread_creat(&tid,NULL,thr_fn,(void *)1);
pthread_join(tid,&tret);
ptintf("thread exit code %ld\n",(long)tret);
exit(0)
}

程序运行结果

thread start
thread push complete
clean up
thread exit code 1

线程与进程的相似之处

进程函数线程函数描述
forkpthread_create创建新的控制流
exitphread_exit从现有的控制流退出
waitpidpthread_join从控制流中得到退出状态
atexitpthread_cleanup_push注册在退出控制流时调用的函数
getpidpthread_self获取控制流的ID
abortpthread_cancel请求控制流的非正常退出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值