海报素材网站推荐,广州市公司网站建设企业,厦门专业做优化的公司,app编辑软件目录
一、线程的创建
进程#xff1a;
线程#xff1a;
线程特点#xff1a; 一个进程中的多个线程共享以下资源#xff1a; 每个线程私有的资源包括#xff1a; Linux线程库#xff1a; 线程创建-pthread_create
二、线程的参数传递
线程结束-pthread_exit
线程查…目录
一、线程的创建
进程
线程
线程特点 一个进程中的多个线程共享以下资源 每个线程私有的资源包括 Linux线程库 线程创建-pthread_create
二、线程的参数传递
线程结束-pthread_exit
线程查看tid函数
三、线程的回收
线程回收-pthread_join:
线程分离pthread_detach:
四、线程回收内存演示 一、线程的创建
进程
进程有独立的地址空间Linux为每个进程创建task_struct每个进程都参与内核调度互不影响
线程
进程在切换时系统开销大很多操作系统引入了轻量级进程LWP同一进程中的线程共享相同地址空间Linux不区分进程、线程
线程特点
通常线程指的是共享相同地址空间的多个任务使用多线程的好处
大大提高了任务切换的效率避免了额外的TLBcache的刷新 一个进程中的多个线程共享以下资源
可执行的指令静态数据进程中打开的文件描述符当前工作目录用户PID用户组ID 每个线程私有的资源包括
线程IDTIDPC程序计数器和相关寄存器堆栈错误号errno优先级执行状态和属性 Linux线程库
pthread线程库中提供了如下基本操作
创建线程回收线程结束线程
同步和互斥机制
信号量互斥锁 Linux线程不是通过内核实现的而是通过pthread线程库实现的。
线程创建-pthread_create
#include pthread.h
int pthread_create(pthread_t *thread,constpthread_attr_t *attr,void *(*routine)(void *),void *arg); 成功返回0失败时返回错误码 thread:线程对象 attr:线程属性NULL代表默认属性 routine:线程执行的函数 arg:传递给routine的参数参数是void *注意传递参数格式 pthread_t pthread_self(void) 查看自己的TID 示例代码
#include pthread.h
#include stdio.h
#include unistd.hint *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 * 注意
主进程的退出它创建的线程也会推出线程创建需要时间如果主进程马上退出那线程不能得到执行
二、线程的参数传递 线程结束-pthread_exit
#include pthread.h
void pthread_exit(void *retval);
结束当前线程retval可被其他线程通过pthread_join获取线程私有资源被释放
线程查看tid函数
#include pthread.h
pthread_t pthread_self(void);
示例代码
#include pthread.h
#include stdio.h
#include unistd.hint *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_self函数 参数传递pthread_create:
pthread_create(pthread_t *thread,constpthread_attr_t *attr,void *(*routine)(void *),void *arg);
最后一个参数。
示例代码
#include pthread.h
#include stdio.h
#include unistd.hvoid *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 pthread.h
#include stdio.h
#include unistd.hvoid *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 pthread.h
#include stdio.h
#include unistd.hvoid *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 pthread.h
#include stdio.h
#include unistd.hvoid *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);}
}
用命令查看进程信息 用命令查看线程信息 线程回收-pthread_join:
#include pthread.h
int pthread_join(pthread_t thread,void **retval);
对于一个默认线程的线程A来说线程占用的资源并不会因为执行结束而得到释放
成功返回0失败返回错误码thread要回收的线程对象调用线程阻塞直到thread结束 *retval接受线程thread的返回值
示例代码
#include stdio.h
#include pthread.h
#include unistd.hvoid *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是阻塞函数如果回收的线程没有结束则一直等待
线程分离pthread_detach:
int pthread_detach(pthread_t thread); 成功0失败错误号
指定该状态线程主动与主控线程断开关系。线程结束后不会产生僵尸线程
示例代码
#include stdio.h
#include pthread.h
#include unistd.hvoid *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 stdio.h
#include pthread.h
#include unistd.hvoid *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 stdio.h
#include pthread.h
#include unistd.hvoid *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代码一样效果。