posix 线程(一)
1.POSIX线程库
与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”开头,要使用这些函数库,要通过引入头文<pthread.h>,而且链接这些线程函数库时要使用编译器命令的“-lpthread”选项。
2.pthread_create函数
(1)功能:创建一个新的线程
(2)原型:int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg);
(3)参数:
thread:线程ID
attr:设置线程的属性,一般设置为NULL表示使用默认属性
start_routine:是个函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数
(4)返回值:成功返回0;失败返回错误码;
3.错误检查
(1)传统的一些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指示错误。
(2)pthreads函数出错时不会设置全局变量errno(而大部分其他POSIX函数会这样做)。而是将错误代码通过返回值返回
(3)pthreads同样提供了线程内的errno变量,以支持它使用errno的代码。对于pthreads函数的错误,建议通过返回值业判定,因为读取返回值要比读取线程内的errno变量的开销小
4.pthread_exit函数
(1)功能:线程终止
(2)原型:void pthread_exit(void *value_ptr);
(3)参数:value_ptr:value_ptr不要指向一个局部变量
(4)返回值:无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身)
5.pthread_join函数
(1)功能:等待线程结束
(2)原型:int pthread_join(pthread_t thread, void **value_ptr);
(3)参数:thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值(用户获取线程的返回值)
(4)返回值:成功返回0;失败返回错误码
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <pthread.h>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>#define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \}while(0)void* thread_routine(void* arg) {int i;for(i=0; i<20; i++) {printf("B");fflush(stdout);usleep(20);//if(3==i)//pthread_exit(const_cast<char*>("ABC"));}sleep(3);return const_cast<char*>("DEF");
}int main(int argc, char* argv[]) {pthread_t tid;int ret;if((ret = pthread_create(&tid, NULL, thread_routine, NULL)) != 0) {fprintf(stderr, "pthead_create:%s\n", strerror(ret));exit(EXIT_FAILURE);}int i;for(i=0; i<20; i++) {printf("A");fflush(stdout);usleep(20);}//sleep(1);void* value;if((ret = pthread_join(tid, &value)) != 0) {fprintf(stderr, "pthead_join:%s\n", strerror(ret));exit(EXIT_FAILURE);}printf("\n");printf("return msg=%s\n", (char*)value); return 0;
}
6.pthread_self函数
(1)功能:返回线程ID
(2)原型:pthread_t pthread_self(void);
(3)返回值:成功返回线程ID
7.pthread_cancel函数
(1)功能:取消一个执行中的线程
(2)原型:int pthread_cancel(pthread_t thread);
(3)参数:thread:线程ID
(4)返回值:成功返回0;失败返回错误码
8.pthread_detach函数
(1)功能:将一个线程分离-如果在新创建的线程结束时主线程没有结束同时也没有调用pthread_join,则会产生僵线程,次问题可以通过设置线程为分离的(detach)来解决
(2)原型:int pthread_detach(pthread_t thread);
9.用线程实现回射客户/服务器
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>#define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \}while(0)void do_service(int conn) {char recvbuf[1024];while(1) {memset(recvbuf, 0, sizeof(recvbuf));int ret = read(conn, recvbuf, sizeof(recvbuf));if(0 == ret) { //server端知道client关闭printf("client close\n");break;} else if(-1 == ret) {ERR_EXIT("read");}fputs(recvbuf, stdout);write(conn, recvbuf, ret);}
}void* thread_routine(void* arg) {//将线程设置分离状态,避免出现僵尸线程pthread_detach(pthread_self());int conn = *(int*)arg;free(arg);do_service(conn);printf("exiting thread ...\n");return NULL;
}int main () {int listenfd;if(( listenfd= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)//if((listenfd= socket(PF_INET, SOCK_STREAM, 0)) <0) ERR_EXIT("socket");struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(5188);//servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");//inet_aton("127.0.0.1", &servaddr.sin_addr);int on = 1;if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)ERR_EXIT("setsockopt");if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))<0)ERR_EXIT("bind");if(listen(listenfd, SOMAXCONN) < 0)ERR_EXIT("listen");struct sockaddr_in peeraddr;socklen_t peerlen = sizeof(peeraddr);int conn;while(1) {if((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0)ERR_EXIT("accept");printf("ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));pthread_t tid;int ret;/*1.if((ret = pthread_create(&tid, NULL, thread_routine, (void*)&conn)) != 0) {竞速问题,当一个连接,accept时候,上一个线程创建conn的值可能会被改变,地址改变2.if((ret = pthread_create(&tid, NULL, thread_routine, (void*)conn)) != 0) {值传递,conn是4个字节,void*指针也是4个字节,平台移植不好*/int* p = (int*)malloc(sizeof(int));*p = conn;if((ret = pthread_create(&tid, NULL, thread_routine, (void*)p)) != 0) {fprintf(stderr, "pthread_create:%s\n", strerror(ret));exit(EXIT_FAILURE);}}close(listenfd);close(conn);return 0;
}
10.进程和线程对比
进程 | 线程 |
pid_t | pthread_t |
fork | pthread_create |
waitpid | pthread_join |
exit | pthread_exit |
在main函数中调用return返回 | 在线程入口函数中调用return |
kill | pthread_cancel |
僵进程waitpid |
僵线程pthread_join pthread_detach |
posix 线程(一)相关推荐
- 【C++ 语言】Visual Studio 配置 POSIX 线程 ( Windows 不支持 POSIX | 配置文件下载 | 库文件说明 | 配置过程 )
文章目录 POSIX 线程局限性 POSIX 线程配置文件下载及目录说明 Windows 动态库与静态库 POSIX 线程配置 ( 项目配置 ) POSIX 线程配置 ( Windows 动态库拷贝 ...
- POSIX线程的同步
当线程运行在同样的线程空间,线程们共享同样的内存和资源.这使它变得很容易对于线程来通信和共享数据,尽管它会发生两种问题:线程阻塞和内存不一致由于线程的同步对共享资源的修改.在这些情况下,线程同步变得很 ...
- 通用线程:POSIX 线程详解,第 2部分——称作互斥对象的小玩意
通用线程:POSIX 线程详解,第 2部分--称作互斥对象的小玩意 Daniel Robbins (drobbins@gentoo.org), 总裁/CEO, Gentoo Technologies, ...
- Posix线程编程指南(4) 线程终止
线程终止方式 一般来说,Posix的线程终止有两种情况:正常终止和非正常终止.线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式:非正常终止是 ...
- POSIX 线程详解
一种支持内存共享的简捷工具 简介: POSIX(可移植操作系统接口)线程是提高代码响应和性能的有力手段.在本系列中,Daniel Robbins 向您精确地展示在编程中如何使用线程.其中还涉及大量幕后 ...
- linux网络编程之posix线程(二)
继续接着上次的posix线程来学习: 回顾一下创建线程的函数: pthread_att_t属性变量是需要进行初始化才能够用的,一定初始化了属性变量,它就包含了线程的多种属性的值,那到底有哪些属性了,下 ...
- linux进程线程同步之 - POSIX线程互斥锁
POSIX线程互斥锁 使用范围:线程同步 本文转自:http://blog.csdn.net/jiebaoabcabc/article/details/37914769 一.函数介绍 1.初始化互斥锁 ...
- POSIX线程库(一)创建第一个pthread线程
对于这个简单的示例,步骤非常简单:创建线程-线程退出-同步退出. 对于POSIX线程相关的函数,无论是变量,还是属性,凡是有要使用的,一般都将会传入对象的地址,目前只有pthread_joint除外, ...
- linux thread model . Linux上posix线程库实现原理讨论
http://blog.csdn.net/fanbird2008/article/details/6752853 Linux上posix线程库实现原理讨论 说明一下,这个问题困扰我好长时间,因为正如使 ...
最新文章
- 小H和游戏(无根树转有根树,思维)难度⭐⭐⭐★
- 关于线程池运行过程中,业务逻辑出现未知异常导致线程中断问题反思
- web前端学习day_02:CSS:三种使用方式/选择器/颜色/背景图片/查看样式/文本/元素显示方式/盒子模型/定位方式/行内对齐/显示层级/防溢出
- MySQL初级培训_Mysql初级学习
- 内核中的 likely() 与 unlikely()
- dubbo调用超时回滚_面试必问之Dubbo面试题
- 程序员的崩溃,是从“你薪资比我高”开始的!
- fzyzojP2291 -- 小添添的庄园之道路修复
- Javascript -- 二叉树(先序,中序,后序实现)
- 电脑刷机重装系统_一键刷机工具
- 复习webpack4之PWA打包配置
- vue从后台下载.zip压缩包文件
- 无需拆机,Kindle 全系列 5.12.2.2 ~ 5.14.2版本如何越狱?如何安装第三方插件
- oracle最简单的分页sql语句,oracle中分页sql语句
- 非直角平面坐标系下的坐标换算
- 试用版:springboot集成pageoffice实现word在线预览可编辑
- FL studio 20简易入门教程 -- 第三篇 -- 菜单栏讲解(下)
- 央视力荐的这套书,让5岁孩子看漫画,秒懂物理,学习早“开窍”!
- 如何打造差异化抖音账号IP?
- vue 视频 时间进度条组件-使用npm组件