行业网站源码网站建设秋实

张小明 2026/1/2 3:15:59
行业网站源码,网站建设秋实,罗湖做网站的,专业网站建设服务报价线程#xff08;pthread#xff09;知识点整理1. 线程概念与特点线程 vs 进程特征进程线程资源分配最小资源分配单位最小执行单位资源共享私有资源空间共享进程资源#xff0c;部分私有通信方式IPC#xff08;复杂#xff09;直接通信#xff08;简单#xff09;创建开销…线程pthread知识点整理1. 线程概念与特点线程 vs 进程特征进程线程资源分配最小资源分配单位最小执行单位资源共享私有资源空间共享进程资源部分私有通信方式IPC复杂直接通信简单创建开销大小轻量级进程稳定性高相对较低效率相对较低高节省30%资源线程优点资源共享共享进程内的全局变量、堆区、文件描述符等高效创建销毁开销小上下文切换快并发性好适合I/O密集型任务简化通信直接共享内存无需复杂IPC线程缺点稳定性差一个线程崩溃可能影响整个进程调试复杂gdb调试需要特殊命令缺乏保护线程间没有内存保护2. POSIX线程编程框架三部曲创建线程 → 线程执行 → 资源回收编译与头文件#include pthread.h // 线程头文件 gcc -g -pthread source.c // 编译命令-lpthread永久设置编译别名# 编辑 ~/.bashrc alias gccgcc -g -pthread # 生效配置 source ~/.bashrc3. 线程创建与管理3.1 创建线程int pthread_create( pthread_t *thread, // 线程ID出参 const pthread_attr_t *attr, // 线程属性NULL为默认 void *(*start_routine)(void *), // 线程回调函数 void *arg // 回调函数参数 );重要特性一次只能创建一个线程主线程退出所有子线程也退出线程ID是CPU维护的唯一标识多个线程可执行同一回调函数3.2 获取线程IDpthread_t pthread_self(void); // 获取当前线程ID3.3 查看线程信息命令ps -eLf # 查看所有线程 ps -eLo pid,ppid,lwp,stat,comm # 查看LWP轻量级进程 pstree # 查看线程树结构4. 线程退出与回收4.1 线程退出方式// 1. 自行退出自杀 void pthread_exit(void *retval); // retval: 退出状态 // 2. 强制退出他杀 int pthread_cancel(pthread_t thread);4.2 线程资源回收int pthread_join(pthread_t thread, void **retval);回收策略有限时间结束 →pthread_join阻塞等待可能休眠阻塞 → 超时后强制回收长期运行 → 不回收可能导致资源泄漏4.3 分离属性// 方法1设置属性 pthread_attr_t attr; pthread_attr_init(attr); pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED); pthread_create(tid, attr, func, NULL); pthread_attr_destroy(attr); // 方法2直接分离 int pthread_detach(pthread_t thread);5. 线程参数传递5.1 传递整型参数// 主线程 int value 100; pthread_create(tid, NULL, func, (void *)(long)value); // 子线程 void *func(void *arg) { int val (int)(long)arg; // 使用val return NULL; }5.2 传递字符串参数// 栈区字符数组危险线程结束后可能失效 char str[] hello; pthread_create(tid, NULL, func, str); // 堆区字符串安全 char *str malloc(128); strcpy(str, hello); pthread_create(tid, NULL, func, str); // 线程结束后需要free5.3 传递结构体参数typedef struct { int id; char name[32]; float score; } Student; // 主线程 Student stu {1, Tom, 90.5}; pthread_create(tid, NULL, func, stu); // 子线程 void *func(void *arg) { Student *stu (Student *)arg; printf(ID:%d, Name:%s, Score:%.1f\n, stu-id, stu-name, stu-score); return NULL; }5.4 计算器示例typedef struct { float a; float b; char op; // - * / float result; } Calculator; void *calc_func(void *arg) { Calculator *calc (Calculator *)arg; switch(calc-op) { case : calc-result calc-a calc-b; break; case -: calc-result calc-a - calc-b; break; case *: calc-result calc-a * calc-b; break; case /: if(calc-b ! 0) calc-result calc-a / calc-b; else calc-result 0; break; } return NULL; }6. 线程返回值返回值传递原理pthread_exit(void *retval)→ 返回地址pthread_join(tid, void **retval)→ 接收地址有效返回地址类型全局变量可直接访问意义不大静态变量生命周期长堆区变量推荐可控制生命周期// 示例返回堆区字符串 void *thread_func(void *arg) { char *result malloc(128); strcpy(result, Thread completed successfully); pthread_exit(result); } int main() { pthread_t tid; char *retval; pthread_create(tid, NULL, thread_func, NULL); pthread_join(tid, (void **)retval); printf(Thread returned: %s\n, retval); free(retval); // 必须释放 return 0; }7. 线程清理函数void cleanup_func(void *arg) { printf(Cleanup: %s\n, (char *)arg); } void *thread_func(void *arg) { // 注册清理函数 pthread_cleanup_push(cleanup_func, Resource cleanup); // 线程工作代码 // do something... // 执行清理函数参数为0则不执行 pthread_cleanup_pop(1); // 1:执行, 0:不执行 return NULL; }8. 线程互斥Mutex互斥锁框架// 1. 定义互斥锁 pthread_mutex_t mutex; // 2. 初始化 pthread_mutex_init(mutex, NULL); // 3. 加锁 pthread_mutex_lock(mutex); // 临界区代码 pthread_mutex_unlock(mutex); // 4. 解锁 // 5. 销毁 pthread_mutex_destroy(mutex);非阻塞加锁int pthread_mutex_trylock(pthread_mutex_t *mutex); // 成功: 0, 失败: EBUSY锁已被占用互斥锁示例共享缓冲区#include stdio.h #include pthread.h #include string.h #include unistd.h char buffer[1024]; pthread_mutex_t mutex; void *writer_thread(void *arg) { char *msg (char *)arg; for(int i 0; i 5; i) { pthread_mutex_lock(mutex); strcpy(buffer, msg); printf(%s wrote: %s\n, msg, buffer); pthread_mutex_unlock(mutex); usleep(100000); // 100ms } return NULL; } int main() { pthread_t tid1, tid2; pthread_mutex_init(mutex, NULL); pthread_create(tid1, NULL, writer_thread, Thread1); pthread_create(tid2, NULL, writer_thread, Thread2); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_mutex_destroy(mutex); return 0; }9. 线程同步信号量信号量框架#include semaphore.h // 1. 定义信号量 sem_t sem; // 2. 初始化二值信号量 sem_init(sem, 0, 1); // 参数信号量pshared(0线程), 初始值 // 3. P操作申请资源 sem_wait(sem); // 临界区 sem_post(sem); // 4. V操作释放资源 // 5. 销毁 sem_destroy(sem);同步示例生产者-消费者#include stdio.h #include pthread.h #include semaphore.h #include string.h char buffer[256]; sem_t sem_empty; // 缓冲区空信号量 sem_t sem_full; // 缓冲区满信号量 void *input_thread(void *arg) { while(1) { sem_wait(sem_empty); // 等待缓冲区空 printf(Enter message: ); fgets(buffer, sizeof(buffer), stdin); buffer[strlen(buffer)-1] \0; // 去掉换行符 if(strcmp(buffer, quit) 0) { sem_post(sem_full); break; } sem_post(sem_full); // 通知处理线程 } return NULL; } void *process_thread(void *arg) { while(1) { sem_wait(sem_full); // 等待数据 if(strcmp(buffer, quit) 0) { sem_post(sem_empty); break; } printf(Processed: Length%lu\n, strlen(buffer)); sem_post(sem_empty); // 通知可继续输入 } return NULL; } int main() { pthread_t tid1, tid2; sem_init(sem_empty, 0, 1); // 初始缓冲区为空 sem_init(sem_full, 0, 0); // 初始无数据 pthread_create(tid1, NULL, input_thread, NULL); pthread_create(tid2, NULL, process_thread, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); sem_destroy(sem_empty); sem_destroy(sem_full); return 0; }10. 综合示例火车票售票系统#include stdio.h #include pthread.h #include unistd.h #include stdlib.h #define TICKET_COUNT 100 int tickets TICKET_COUNT; pthread_mutex_t mutex; int window1_count 0; int window2_count 0; void *sell_tickets(void *arg) { char *window_name (char *)arg; while(1) { pthread_mutex_lock(mutex); if(tickets 0) { printf(%s 卖出车票 %d\n, window_name, TICKET_COUNT - tickets 1); tickets--; if(strcmp(window_name, 窗口1) 0) window1_count; else window2_count; pthread_mutex_unlock(mutex); usleep(100000); // 模拟卖票时间 } else { pthread_mutex_unlock(mutex); break; } } return NULL; } int main() { pthread_t tid1, tid2; pthread_mutex_init(mutex, NULL); pthread_create(tid1, NULL, sell_tickets, 窗口1); pthread_create(tid2, NULL, sell_tickets, 窗口2); pthread_join(tid1, NULL); pthread_join(tid2, NULL); printf(\n售票统计:\n); printf(窗口1卖出: %d张\n, window1_count); printf(窗口2卖出: %d张\n, window2_count); printf(总共卖出: %d张\n, TICKET_COUNT - tickets); pthread_mutex_destroy(mutex); return 0; }11. 线程控制函数对比进程操作线程操作功能fork()pthread_create()创建getpid()pthread_self()获取IDexit()pthread_exit()退出wait()pthread_join()等待回收kill()pthread_cancel()强制终止atexit()pthread_cleanup_push/pop()清理函数12. 死锁与预防死锁产生条件互斥条件资源只能被一个线程使用请求与保持线程持有资源并请求新资源不可剥夺资源只能由持有者释放循环等待线程间形成等待环预防策略按顺序申请资源所有线程按相同顺序申请锁使用超时机制pthread_mutex_trylock 超时重试避免嵌套锁尽量减少锁的嵌套层次使用资源层级为资源分配优先级避免死锁示例// 按固定顺序获取锁 void safe_operation(pthread_mutex_t *lock1, pthread_mutex_t *lock2) { // 总是先获取lock1再获取lock2 pthread_mutex_lock(lock1); pthread_mutex_lock(lock2); // 临界区操作 pthread_mutex_unlock(lock2); pthread_mutex_unlock(lock1); }13. 线程调度与让出CPUpthread_yield(); // 主动让出CPU建议使用 usleep(1000); // 休眠方式让出CPU14. 综合练习餐厅管理系统#include stdio.h #include pthread.h #include semaphore.h #include string.h #include stdlib.h #include unistd.h #define TABLE_COUNT 3 typedef struct { char name[100]; int total_num; int call_num; pthread_mutex_t lock; } Restaurant; Restaurant rest; sem_t tables; // 餐桌信号量 void *customer(void *arg) { int id *(int *)arg; printf(顾客%d [%s] 正在用餐...\n, id, rest.name); sleep(rand() % 3 1); // 用餐时间 printf(顾客%d [%s] 离开\n, id, rest.name); sem_post(tables); // 释放餐桌 free(arg); return NULL; } void *waiter(void *arg) { while(1) { pthread_mutex_lock(rest.lock); if(rest.call_num rest.total_num) { sem_wait(tables); // 等待空桌 int *id malloc(sizeof(int)); *id rest.call_num; pthread_t tid; pthread_create(tid, NULL, customer, id); pthread_detach(tid); printf(服务员叫号: %d [%s]\n, rest.call_num, rest.name); } else { pthread_mutex_unlock(rest.lock); break; } pthread_mutex_unlock(rest.lock); sleep(1); } return NULL; } int main() { pthread_t waiter_tid; // 初始化 sem_init(tables, 0, TABLE_COUNT); pthread_mutex_init(rest.lock, NULL); rest.total_num 0; rest.call_num 0; // 输入顾客信息 printf(请输入顾客姓名: ); fgets(rest.name, sizeof(rest.name), stdin); rest.name[strlen(rest.name)-1] \0; printf(请输入顾客总数: ); scanf(%d, rest.total_num); getchar(); // 清除缓冲区 // 启动服务员线程 pthread_create(waiter_tid, NULL, waiter, NULL); pthread_join(waiter_tid, NULL); // 清理 sem_destroy(tables); pthread_mutex_destroy(rest.lock); printf(所有顾客已服务完毕!\n); return 0; }15. 线程调试技巧GDB调试线程gdb ./a.out (gdb) run (gdb) info threads # 查看所有线程 (gdb) thread 2 # 切换到线程2 (gdb) bt # 查看线程调用栈 (gdb) thread apply all bt # 查看所有线程调用栈调试建议编译带调试信息gcc -g -pthread使用线程局部变量避免全局变量冲突添加调试输出打印线程ID和状态逐步测试先测试单线程再测试多线程16.总结多线程编程的关键在于正确处理共享资源的同步与互斥问题。合理使用互斥锁和信号量可以避免竞态条件和死锁同时需要注意线程的生命周期管理和资源回收。在实际开发中应根据具体需求选择合适的线程模型和同步机制。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

营销型网站建设遨龙网页制作成品模板网站

PaddlePaddle边缘计算部署:Jetson设备上的实测性能分析 在智能制造工厂的质检流水线上,一台搭载Jetson Orin Nano的小型视觉盒子正以每秒5帧的速度扫描产品标签。它不仅要识别模糊印刷和反光背景下的文字,还要准确读取中文字符——这在过去往…

张小明 2025/12/29 13:13:24 网站建设

网站建站ddpui培训

GPT-SoVITS在自动驾驶语音交互中的场景化应用在智能座舱逐渐成为“第三生活空间”的今天,用户对车载语音助手的期待早已超越了“能听会说”的基础功能。人们希望它不只是一个冷冰冰的导航工具,而是像家人一样熟悉、像朋友一样亲切——能用父亲的声音提醒…

张小明 2025/12/29 16:03:16 网站建设

网站备案 网站名称wordpress的小程序

这几天小白好像更新没有了动力……也不知道小伙伴想看哪方面的教程,或者唠唠嗑?小白当初也是雄心壮志,一咬牙一跺脚,豪掷3000大洋,组了台梦想中的NAS!配置单亮出来,那叫一个技术宅的浪漫&#x…

张小明 2025/12/29 16:29:36 网站建设

网站上传的工具网站网络

AI伦理实践:LobeChat内置内容过滤机制解析 在大语言模型(LLM)加速落地的今天,AI生成内容的安全问题已从“可选项”变为“必答题”。无论是企业客服、教育助手还是私人知识库,用户与AI的每一次对话都潜藏着风险——不当…

张小明 2025/12/29 17:11:39 网站建设

问答网站开发免费建手机商城网站

### Java设计模式实战:从面向对象原则到架构设计的最佳实践 面向对象原则 面向对象编程是一种程序设计范式,它以对象作为基本单元,对对象进行抽象、封装、继承和多态等操作。面向对象编程有七大原则,即SOLID原则:单一职…

张小明 2025/12/29 17:12:35 网站建设