ps aux -L 查看线程信息 且显示进程状态
使用进程的缺点: 进程切换 系统开销较大
开销大的原因 :切换时需要频繁刷新 cache(类似于缓冲区) 和TLB
linux不区分线程 进程
线程其实也属于进程 只不过是特殊的进程 是一种可以共享地址空间的进程
使用线程的优点:同一进程的线程会共享相同的地址空间
当使用多线程时 会大大提高任务切换的效率
避免多次刷新cache和TLB
通过全局变量即可交换数据 使通信变得非常容易
缺点:
多个线程访问共享资源时 需要同步或互斥机制
一个进程中的线程可共享的资源:
可执行指令
静态数据
进程中打开的文件描述符
当前工作目录
用户D
用户组ID
每个线程私有的资源:
线程ID
pc(程序计数器)和相关寄存器
堆栈
错误号
优先级
执行状态和属性
创建线程
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg);
成功返回0 失败返回错误码
thread 线程对象
attr 指定线程属性 NULL代表默认属性
routine 线程执行函数 (参数是一个函数指针)
arg 传递给routine这个函数的参数
线程回收
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval)
成功返回0 失败返回错误码
thread 要回收的线程对象 如果线程未结束 调用线程会阻塞 直到thread结束
*retval 接受线程的返回值
结束线程
#include <pthread.h>
void pthread_exit(void *retval)
如果用exit()会结束所有线程
retval可别其他线程通过pthread_join()获取
retval需要被设定成全局变量才能被其他进程操作 否则只能被当前进程操作
Ps:
char message[32] = {"hello world!"}
void *thread_func(void *arg); //创建进程参数的实现函数
int main()
{
pthread_t a_thread;
void *result;
if(pthread_create(&a_thread, NULL, thread_func), NULL) != 0)
{
printf("fail to pthread_creat");
exit(-1);
}
pthread_join(&a_thread, &result);
printf("result is %s\n", result);
printf("message is %s\n", message);
return 0;
}
//重写实现函数
void thread_func(void *arg)
{
sleep(1);
strcpy(message, "marked by thread");
pthread_exit("thank you for waiting for me");
}
运行命令:
gcc -o test test.c -lpthread
./test
打印结果:
thank you to waiting for me
marked by thread