福州品牌网站设计,网站的架构与建设,电商后台管理系统,西安关键字优化哪家好目录
pthread_create -- 创建线程
参数
返回值 代码 -- 不传 args#xff1a;
编译时带 -lpthread
运行结果
为什么输出混杂#xff1f;
如何证明两个线程属于同一个进程#xff1f; 如何证明是两个执行流#xff1f;
什么是LWP#xff1f;
代码 -- 传 args
编译时带 -lpthread
运行结果
为什么输出混杂
如何证明两个线程属于同一个进程 如何证明是两个执行流
什么是LWP
代码 -- 传 args
运行结果 pthread_self -- 线程标识符
代码
LWP标识符 和 线程标识符的区别
pthread_join -- 等待线程退出 前言主线程比新线程先退出
参数
返回值 代码 -- 不获取退出状态
代码 -- 获取退出状态 编辑
pthread_exit -- 终止线程
前言新、主线程共享地址空间
参数
作用
代码
pthread_cancel -- 取消线程
参数
返回值
代码 pthread_create -- 创建线程
#include pthread.hint pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数 thread: 指向一个 pthread_t 类型的指针用于存储新创建线程的标识符是输出型参数。 attr: 指向一个 pthread_attr_t 类型的指针这个参数可以用来设置线程的属性如栈大小、调度策略等。如果不需要特别设置线程属性可以传递 NULL。 start_routine: 这是一个函数指针指向新线程开始执行的函数。该函数必须接受一个 void* 类型的参数并返回一个 void* 类型的结果。 arg: 这个参数将被传递给 start_routine 函数作为其唯一的参数。如果你不想传递任何参数可以使用 NULL。 返回值 如果函数调用成功返回值为 0。 如果发生错误返回值为一个非零的错误代码。 代码 -- 不传 args
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;void* newthreadRun(void* args)
{while(1){coutI am new threadendl;sleep(1);}
}
int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,nullptr);while(1){coutI am main threadendl;sleep(1);}return 0;
}
编译时带 -lpthread 这里需要了解一点小故事用户知道线程和进程但不知道轻量级进程而Linux中没有真线程Linux中没有线程相关的系统调用只有轻量级进程的系统调用为了让用户和系统达成一致系统将轻量级进程的系统调用进行封装转换成线程相关的接口语义提供给用户也就有了pthread库即原生线程库这个库既不属于C语言也不属于C所以在Linux系统中编写多线程时都必须在编译时带上 -lpthread。 在 Linux 中编译使用 Pthreads 的程序时通常需要链接 Pthreads 库。这可以通过在编译命令中添加 -lpthread 选项来实现。-lpthread 选项不仅告诉编译器链接 Pthreads 库还会启用一些必要的编译器选项以确保线程支持的正确性和性能。 如果不使用 -lpthread 选项编译器可能会报错或生成不可用的二进制文件。 thread:thread.ccg -o $ $^ -stdc11 -lpthread.PHONY:clean
clean:rm -f thread
运行结果 可以看出两个执行流同时输出信息。同时也可以看出一开始新、主线程打印的消息混在一起了后面才分开来这是正常现象。 为什么输出混杂 在多线程程序中多个线程同时向终端输出信息时可能会出现输出混杂的情况。这是因为每个线程的输出操作并不是原子的原子操作即要么完全执行要么根本不执行即一个线程可能在另一个线程已经开始输出但还没有完成输出时就开始了自己的输出这种现象通常称为“输出交错”或“输出混杂”。 如何证明两个线程属于同一个进程 当不传 args 版本的代码运行时输入命令 ps ajx | head -1 ps ajx | grep thread 筛选出 thread 进程可以看出只有一个进程被调度 如何证明是两个执行流 当代码运行起来时输入命令 ps -aL | head -1 ps -aL | grep thread 可以查看线程的信息可以看出两个线程的 pid 一样即属于同一个进程而 LWP 不同则说明一个进程中有两个执行流 ps -aL-a显示所有进程包括其他用户的进程-L 显示每个线程的详细信息。 什么是LWP
LWPLight Weight Process是轻量级进程的缩写在 Linux 中LWP 通常被称为“线程”。 代码 -- 传 args
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestringstring toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){std::coutthreadname is running: cnt, pid: getpid() mythread id: toHex(pthread_self())std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);pthread_join(tid,nullptr);return 0;
}
运行结果 pthread_self -- 线程标识符
#include pthread.h
pthread_t pthread_self(void); 该函数用于获取当前线程的标识符pthread_t 类型。 代码
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestringstring toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{while(1){coutI am new thread, new thread tid: toHex(pthread_self()), pid: getpid()endl;sleep(1);}
}
int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,nullptr);while(1){coutI am main thread, main thread tid: toHex(pthread_self()), pid: getpid()endl;sleep(1);}return 0;
} 可以看出新、主线程的线程标识符 tid 的值不一样同时也可以看出LWP 和线程标识符 tid的值是不一样的 LWP标识符 和 线程标识符的区别 LWPLight Weight Process标识符和线程标识符Thread IdentifierTID在数值上通常是不一样的。虽然它们在概念上密切相关但它们表示的是不同的标识符用途和获取方式也有所不同。
pthread_join -- 等待线程退出 前言主线程比新线程先退出
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestringstring toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;//新线程运行5秒while(cnt--){std::coutthreadname is running: cnt, pid: getpid() mythread id: toHex(pthread_self())std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);sleep(1);//因为主线程没有阻塞等待新线程1秒后主线程先退出了std::coutmain thread quitstd::endl;return 0;
} 因为主线程没有阻塞等待新线程退出1秒后主线程退出了主线程退出了就等同于整个进程退出了分配给进程的资源都被释放了所以所有的线程都要退出所以新线程还没执行完就被退出了通常需要主线程最后结束。线程的退出也需要wait不然会发生内存泄漏问题。 #include pthread.hint pthread_join(pthread_t thread, void **value_ptr); 该函数用于等待指定的线程终止并获取该线程的退出状态。 参数 thread要等待的线程的标识符pthread_t 类型可以调用 pthread_self 函数获取。 value_ptr输出型参数用于存储线程的退出状态。如果不需要获取退出状态可以传递 NULL。 返回值 等待线程退出成功返回 0。 等待线程退出失败返回非零错误码。 代码 -- 不获取退出状态
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestringstring toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){std::coutthreadname is running: cnt, pid: getpid() mythread id: toHex(pthread_self())std::endl;sleep(1);}return nullptr;
}
int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);int npthread_join(tid,nullptr);//获取返回值std::coutmain thread quit, nnstd::endl;return 0;
} 新线程正常退出故返回值为 0. 代码 -- 获取退出状态
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestringstring toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){std::coutthreadname is running: cnt, pid: getpid() mythread id: toHex(pthread_self())std::endl;sleep(1);}return (void*)123;
}
int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);void* retnullptr;int npthread_join(tid,ret);//ret强转为long long是为了避免精度损失std::coutmain thread quit, nn,main thread get a ret:(long long)retstd::endl;return 0;
} 线程的退出状态其实就是线程执行的任务函数的返回值。 pthread_exit -- 终止线程
前言新、主线程共享地址空间
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestring
int g_val100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){printf(new thread, g_val:%d,g_val:%p\n,g_val,g_val);g_val;//在新线程中改变g_val的值sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);int cnt10;while(cnt--){//主线程不改变g_val的值printf(main thread, g_val:%d,g_val:%p\n,g_val,g_val);sleep(1);}void* retnullptr;int npthread_join(tid,ret);std::coutmain thread quit, nn,main thread get a ret:(long long)retstd::endl;return 0;
} 可以看出新线程修改了 g_val 的值主线程中 g_val 的值也被修改了说明新、主线程共享了地址空间看到的是同一个变量而不是和进程一样发生写时拷贝。 #includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestring
int g_val100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){printf(new thread, g_val:%d,g_val:%p\n,g_val,g_val);g_val;//故意对空指针进行解引用int *pnullptr;*p10;sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);int cnt10;while(cnt--){printf(main thread, g_val:%d,g_val:%p\n,g_val,g_val);sleep(1);}void* retnullptr;int npthread_join(tid,ret);std::coutmain thread quit, nn,main thread get a ret:(long long)retstd::endl;return 0;
} 在新线程中故意对野指针进行解引用结果新、主线程一起退出了这是因为在同一个进程中运行的所有线程共享相同的地址空间这意味着如果一个线程造成了段错误segmentation fault那么这个错误会影响到整个进程而不仅仅是单个线程。操作系统通常会终止整个进程以防止进一步的损坏。 #include pthread.hvoid pthread_exit(void *value_ptr);
参数 value_ptr一个指向指针的指针用于存储线程的退出状态。 这个值可以被 pthread_join 函数捕获并使用。如果不需要传递退出状态可以传递 NULL。 作用 终止当前线程调用 pthread_exit 的线程会立即终止其执行。 传递退出状态可以通过 value_ptr 参数传递一个退出状态这个状态可以被 pthread_join 函数捕获。 代码
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestring
int g_val100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){printf(new thread, g_val:%d,g_val:%p\n,g_val,g_val);g_val;sleep(1);}pthread_exit((void*)123);
}int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);void* retnullptr;int npthread_join(tid,ret);std::coutmain thread quit, nn,main thread get a ret:(long long)retstd::endl;return 0;
} pthread_cancel -- 取消线程
#include pthread.hint pthread_cancel(pthread_t thread);
参数 thread要取消的线程的标识符pthread_t 类型。 返回值 取消线程成功返回 0。 取消线程失败返回非零错误码。 代码
#includeiostream
#includepthread.h
#includeunistd.h
using namespace std;
#includestring
int g_val100;
string toHex(pthread_t tid)
{char buffer[64];snprintf(buffer,sizeof(buffer),0x%lx,tid);return buffer;
}
void* newthreadRun(void* args)
{std:string threadname(char*)args;int cnt5;while(cnt--){printf(new thread, g_val:%d,g_val:%p\n,g_val,g_val);g_val;sleep(1);}pthread_exit((void*)123);
}int main()
{pthread_t tid;pthread_create(tid,nullptr,newthreadRun,(void*)thread-1);pthread_cancel(tid);void* retnullptr;int npthread_join(tid,ret);std::coutmain thread quit, nn,main thread get a ret:(long long)retstd::endl;return 0;
} 线程的退出状态为 -1表示线程被取消。