进程概述
进程:有独立的进程地址空间,有独立的PCB 线程:没有独立的地址空间,是共享的,有独立的PCB Linux下,线程是最小的执行单位,进程是最小的分配资源的单位
LWP: 轻量级进程也就是线程 命令 ps -Lf pid 可以查看该进程的线程号
线程创建
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
返回值:成功返回0 失败返回perror
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<unistd.h>
void* tfn(void*arg)
{
printf("phread:pid = %d,tid = %lu\n",getpid(),pthread_self());
}
int main()
{
pthread_t tid;
printf("mian : pid = %d ,tid = %lu\n",getpid(),pthread_self());
int ret=pthread_create(&tid,NULL,tfn,NULL);
if(ret!=0)
{
perror("pthread");
}
sleep(1);
return 0;
}
线程退出
pthread_exit函数
void pthread_exit(void *retval);
参数是传出参数,此函数的作用是终止一个调用他的线程 eg:循环创建五个子线程,终止第三个子线程
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
void func()
{
pthread_exit(NULL);
}
void*tfn(void*argv)
{
int i=(int)argv;
sleep(i);
if(i==2)
{
func();
}
printf("I am %d ,pthread: pid = % d,tid = %lu\n",i+1,getpid(),pthread_self());
}
int main()
{
int i=0;
int ret;
pthread_t tid;
for(i=0;i<5;i++)
{
ret=pthread_create(&tid,NULL,tfn,(void*)i);
if(ret!=0)
{
perror("pthread_create");
exit(1);
}
}
printf("i am main\n");
pthread_exit(NULL);
}
执行结果:
pthread_cancel函数
int pthread_cancel(pthread_t thread);
回收特定线程,传入参数是要终止的线程id 为了看到效果,用一个死循环代码来展示效果
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
void*tnf(void*arg)
{ while(1)
{
printf(" thread: pid = %d,tid = %lu\n",getpid(),pthread_self());
sleep(1);
}
}
int main()
{
pthread_t tid;
int ret =pthread_create(&tid,NULL,tnf,NULL);
if(ret<0)
{
perror("create");
exit(1);
}
sleep(3);
ret=pthread_cancel(tid);
while(1);
return 0;
}
效果:
pthread_join函数(回收线程)
阻塞等待线程退出,并且获得线程退出状态(返回值),很类似于进程中的waitpid函数
int pthread_join(pthread_t thread, void **retval);
参数: thread 要堵塞等待退出的线程id retval 退出状态 eg:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
typedef struct pdf
{
int var;
char arr[100];
}pdf;
void*tnf(void*arg)
{
struct pdf* p1;
p1=(pdf*)malloc(sizeof(pdf));
p1->var=100;
strcpy(p1->arr,"hello world");
return (void*)p1;
}
int main()
{
pthread_t tid;
pdf* p1;
int ret =pthread_create(&tid,NULL,tnf,NULL);
pthread_join(tid,(void**)&p1);
printf("tar=%d,arr=%s\n",p1->var,p1->arr);
return 0;
}
结果:
线程分离pthread_detach
线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其它线程获取,而直接自己自动释放
int pthread_detach(pthread_t thread);
参数:所要分离的线程
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
void*tfn(void*arg)
{
printf("thread : pid = %d, tid = %lu\n",getpid(),pthread_self());
return NULL;
}
int main()
{
pthread_t tid;
int ret=pthread_create(&tid,NULL,tfn,NULL);
if(ret!=0)
{
perror("create error");
exit(1);
}
sleep(2);
ret=pthread_detach(tid);
if(ret!=0)
{
fprintf(stderr,"pthread_deach 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);
}
return 0;
}
结果: 当我们对线程分离后,再当我们使用线程退出函数就会报无效参数的错误
线程属性
属性值不能直接设置,须使用相关函数进行操作,初始化的函数为pthread_attr_init,这个函数必须在pthread_create函数之前调用。之后须用pthread_attr_destroy函数来释放资源。线程属性主要包括如下属性:作用域(scope)、栈尺寸(stack size)、栈地址(stack address)、优先级(priority)、分离的状态(detached state)、调度策略和参数(scheduling policy and parameters)。默认的属性为非绑定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。
所用函数
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachst
..........还有很多函数
int pthread_attr_destroy(pthread_attr_t *attr);
使用
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
void*tfn(void*argv)
{
printf("thread : pid=%d,tid=%lu\n",getpid(),pthread_self());
return NULL;
}
int main()
{
pthread_attr_t attr;
pthread_t tid;
int ret=pthread_attr_init(&attr);
if(ret!=0)
{
fprintf(stderr,"attr_init error:%s\n",strerror(ret));
exit(1);
}
ret=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if(ret!=0)
{
fprintf(stderr,"attr_setdeatachstate error:%s\n",strerror(ret));
exit(1);
}
ret=pthread_create(&tid,&attr,tfn,NULL);
if(ret!=0)
{
fprintf(stderr,"attr_create error:%s\n",strerror(ret));
exit(1);
}
ret=pthread_attr_destroy(&attr);
if(ret!=0)
{
fprintf(stderr,"attr_destroy error:%s\n",strerror(ret));
exit(1);
}
sleep(1);
ret=pthread_join(tid,NULL);
if(ret!=0)
{
fprintf(stderr,"create error:%s\n",strerror(ret));
exit(1);
}
return 0;
}
|