目录
一、线程的创建
进程:
线程:
线程特点:
一个进程中的多个线程共享以下资源:
每个线程私有的资源包括:
Linux线程库:
线程创建-pthread_create
二、线程的参数传递
线程结束-pthread_exit
线程查看tid函数
三、线程的回收
线程回收-pthread_join:
线程分离pthread_detach:
四、线程回收内存演示
Linux线程不是通过内核实现的,而是通过pthread线程库实现的。
#include
int pthread_create(pthread_t *thread,const
pthread_attr_t *attr,void *(*routine)(void *),void *arg);
成功返回0,失败时返回错误码
thread:线程对象
attr:线程属性,NULL代表默认属性
routine:线程执行的函数
arg:传递给routine的参数,参数是void *,注意传递参数格式
pthread_t pthread_self(void) 查看自己的TID
示例代码:
#include
#include
#include
int *testThread(char *arg)
{
printf("This is a thread\n");
return NULL;
}
int main()
{
pthread_t tid;
int ret;
ret = pthread_create(&tid,NULL,(void *)testThread,NULL); //testThread强制返回void *
printf("This is main thread\n");
sleep(1);
}
编译:
gcc creatP_t.c -lpthread
结果:
常见错误:
creatP_t.c: In function ‘main’:
creatP_t.c:14:36: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types]
ret = pthread_create(&tid,NULL,testThread,NULL);
^
In file included from creatP_t.c:1:0:
/usr/include/pthread.h:233:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘int * (*)(char *)’
解决方法:
ret = pthread_create(&tid,NULL,(void *)testThread,NULL); //testThread强制返回void *
注意:
#include
void pthread_exit(void *retval);
#include
pthread_t pthread_self(void);
示例代码:
#include
#include
#include
int *testThread(char *arg)
{
printf("This is a thread, pit = %d, tid = %lu\n",getpid(),pthread_self());
pthread_exit(NULL);
printf("after exit\n");
//return NULL;
}
int main()
{
pthread_t tid;
int ret;
ret = pthread_create(&tid,NULL,(void *)testThread,NULL); //testThread强制返回void *
printf("This is main thread, tid = %lu\n",tid);
sleep(1);
}
运行结果:
获取线程id两种方法:
参数传递pthread_create:
pthread_create(pthread_t *thread,const
pthread_attr_t *attr,void *(*routine)(void *),void *arg);
最后一个参数。
示例代码:
#include
#include
#include
void *testThread(void *arg)
{
printf("This is a thread, pit = %d, tid = %lu\n",getpid(),pthread_self());
printf("input arg = %d\n",*(int *)arg);//先将arg参数转换为int *指针类型,再通过*进行解引用
pthread_exit(NULL);
printf("after exit\n");
//return NULL;
}
int main()
{
pthread_t tid;
int ret;
int arg = 5;
ret = pthread_create(&tid,NULL,testThread,(void *)&arg); //testThread强制返回void *
printf("This is main thread, tid = %lu\n",tid);
sleep(1);
}
运行结果:
注意:void *不能直接进行* arg,要强制类型转换为*(int *)arg ,否则会产生如下错误:
值传递代码示例:
#include
#include
#include
void *testThread(void *arg)
{
printf("This is a thread, pit = %d, tid = %lu\n",getpid(),pthread_self());
printf("input arg = %d\n",(int)arg);//先将arg参数转换为int *指针类型,再通过*进行解引用
pthread_exit(NULL);
printf("after exit\n");
//return NULL;
}
int main()
{
pthread_t tid;
int ret;
int arg = 5;
ret = pthread_create(&tid,NULL,testThread,(void *)arg); //此时arg表示指针指向的一个值
printf("This is main thread, tid = %lu\n",tid);
sleep(1);
}
编译会出现警告,但是不影响参数传递:
运行结果:
参数传递注意:
创建多个线程代码示例:
#include
#include
#include
void *testThread(void *arg)
{
printf("This is a thread, pit = %d, tid = %lu\n",getpid(),pthread_self());
printf("input arg = %d\n",(int)arg);//先将arg参数转换为int *指针类型,再通过*进行解引用
pthread_exit(NULL);
printf("after exit\n");
//return NULL;
}
int main()
{
pthread_t tid[5];
int ret;
int arg = 5;
int i;
for(i = 0; i < 5; i++)
{
ret = pthread_create(&tid[i],NULL,testThread,(void *)i); //testThread强制返回void *
printf("This is main thread, tid = %lu\n",tid[i]);
}
sleep(1);
}
运行结果:
注意:
原因:栈被破坏了(数组越界)
运行代码实例:
#include
#include
#include
void *testThread(void *arg)
{
printf("This is a thread, pit = %d, tid = %lu\n",getpid(),pthread_self());
printf("input arg = %d\n",(int)arg);//先将arg参数转换为int *指针类型,再通过*进行解引用
//pthread_exit(NULL);
while (1)
{
sleep(1);
}
printf("after exit\n");
//return NULL;
}
int main()
{
pthread_t tid[5];
int ret;
int arg = 5;
int i;
for(i = 0; i < 5; i++)
{
ret = pthread_create(&tid[i],NULL,testThread,(void *)i); //testThread强制返回void *
printf("This is main thread, tid = %lu\n",tid[i]);
}
while (1)
{
sleep(1);
}
}
用命令查看进程信息:
用命令查看线程信息:
#include
int pthread_join(pthread_t thread,void **retval);
对于一个默认线程的线程A来说,线程占用的资源并不会因为执行结束而得到释放
示例代码:
#include
#include
#include
void *func(void *arg)
{
printf("This is child thread\n");
sleep(1);
pthread_exit("thread return");
}
int main()
{
void *retv;
pthread_t tid;
pthread_create(&tid,NULL,func,NULL);
pthread_join(tid,&retv);//线程没退出,此处一直阻塞状态
printf("thread ret = %s\n",(char *)retv);
sleep(1);
}
运行结果:
注意:
pthread_join是阻塞函数,如果回收的线程没有结束,则一直等待
int pthread_detach(pthread_t thread);
成功:0,失败:错误号
示例代码:
#include
#include
#include
void *func(void *arg)
{
pthread_detach(pthread_self());
printf("This is child thread\n");
sleep(1);
pthread_exit("thread return");
}
int main()
{
void *retv;
pthread_t tid[5];
int i;
for (i = 0; i < 5; i++)
{
pthread_create(&tid[i],NULL,func,NULL);
//pthread_detach(tid);
}
while (1)
{
sleep(1);
}
}
运行结果:
通过线程属性来设置分离态:
示例代码:
#include
#include
#include
void *func(void *arg)
{
//pthread_detach(pthread_self());
printf("This is child thread\n");
sleep(1);
pthread_exit("thread return");
}
int main()
{
void *retv;
pthread_t tid[5];
int i;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
for (i = 0; i < 5; i++)
{
pthread_create(&tid[i],NULL,func,NULL);
//pthread_detach(tid);
}
while (1)
{
sleep(1);
}
}
示例代码:
#include
#include
#include
void *func(void *arg)
{
printf("This is child thread\n");
sleep(25);
pthread_exit("thread return");
}
int main()
{
void *retv;
pthread_t tid[100];
int i;
for (i = 0; i < 100; i++)
{
pthread_create(&tid[i],NULL,func,NULL);
}
for (i = 0; i < 100; i++)
{
pthread_join(tid[i],&retv);
printf("thread ret=%s\n",(char *)retv);
}
while (1)
{
sleep(1);
}
}
代码运行期间:
查看进程Pid
使用top命令动态查看内存大小,可以看出内存会变小。
使用pthread_detach代码一样效果。