POSIX线程编程(上):基本概念、特点和常用函数

一、基本概念

1、线程就是程序的执行路线,它是进程内部的控制序列,是资源的调度单位的基本单位,或者说它是进程的一部分。
2、线程是轻量级的,没有自己独立的内存资源、代码段、数据区、堆区、环境变量、命令行参数、文件描述符、信号处理函数、当前目录等资源。
3、线程拥有自己独立的栈内存,也就是有自己独立的局部变量,还有独立的线各ID、错误码、信号掩码。
4、一个进程可以同时拥有多个线程,也就是拥有多个执行路线,其中一个叫主线程。
5、线程是进程的一部分,而且是负责执行的那部分。

二、基本特点

1、线程是进程的实体,可作为系统独立的任务高度和分派的基本单位
2、线程有不同的状态,系统提供了线程控制的接口,如:创建线程、销毁线程、控制线程等
3、线程不拥有自己的资源,只拥有从属于进程的全部资源,所有的资源分配都是面向进程的。
4、进程中可以有多个线程,它们可以并发的执行,可以执行相同的代码也可以执行不同的代码。
5、一个进程的多个线程都在同一个地址空间内活动,因此相对于进程,线程的系统开销小,任务切换快
6、线程之间不需要数据交换,也就不需要类似IPC的特殊通信机制,因此线程简单而高效。
7、线程之间有优先级的差异。

三、POSIX线程

1、UNIX和Linux系统早期是没有线程概念的,线程首先使用在windows系统中,后面发现线程有它独特的优势,然后各个厂商各自提供私有的线程库,而且接口、实现的差异比较大,不易移植。
2、在1995年制定的POSIX标准中,规定了统一的线程编程接口,遵循POSIX标准的线程实现被统称为POSIX线程,也叫pthread。
3、pthread包含一个头文件 pthread.h 和一个共享库 libpthread.so。因此在编译线程代码时需要-lpthread参数。

四、线程函数

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

功能:创建一个线程
thread:线程ID,输出参数
attr:线程属性,即可能是输出,也可能是输入,NULL表示缺省。
start_routine:函数指针,线程的执行入口,参数和返回值都是void*。
启动线程的本质就是调用一个函数,只不过是在一新的线程中调用,如果该函数执行结束线程就结束了。
arg:传递给入口函数的参数。
线程的入口函数的调用者是内核,而不是用户代码。
线程不需要传递全局变量,因为是共享的,静态变量、结构变量、堆内存、只需要传递指针即可。
注意:尽量不要传递栈内存地址,因为线程的栈内存是相互独立的。
返回值:成功返回0,失败返回错误码。

pthread_t pthread_self(void);

功能:获取当前线程的ID

注意:多线程在解决复杂问题或大量计算时,如果有硬件支持速度将大提高,如果是单核CPU速度反而会降低。
注意:线程相关的接口如果错误并不会改变全局的errno,而是返回错误编码,只能借助strerror函数获取错误信息。

int pthread_join(pthread_t thread, void **retval);

功能:以阻塞方式等待子线程结束,类似进程的wait函数。
thread:线程ID
retval:获取线程结束的返回值
返回值:成功返回0,失败返回错误码。
下面看一个多线程拷贝的程序。

// #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef struct Info
{
	char src_path[256];
	char dest_path[256];
	int start;
	int end;
}Info;

void* copy(void* arg)
{
	Info* info = arg;
	int src_fd = open(info->src_path,O_RDONLY);
	if(0 > src_fd)
	{
		perror("open");
		pthread_exit(NULL);
	}

	int dest_fd = open(info->dest_path,O_WRONLY|O_CREAT,0644);
	if(0 > dest_fd)
	{
		perror("open");
		pthread_exit(NULL);
	}

	char* buf = malloc(info->end-info->start);
	lseek(src_fd,info->start,SEEK_SET);
	int ret = read(src_fd,buf,info->end-info->start);
	lseek(dest_fd,info->start,SEEK_SET);
	write(dest_fd,buf,ret);
	
	close(src_fd);
	close(dest_fd);
}

int main(int argc,const char* argv[])
{
	if(3 !=	argc)
	{
		puts("User:cp src dest");
		return 0;
	}

	int fd = open(argv[1],O_RDONLY);
	if(0 > fd)
	{
		perror("open");
		return -1;
	}

	int bytes = lseek(fd,0,SEEK_END);

	pthread_t tid[5];
	Info* info = malloc(sizeof(Info)*5);

	for(int i=0; i<5; i++)
	{
		strcpy(info[i].src_path,argv[1]);
		strcpy(info[i].dest_path,argv[2]);
		info[i].start = i*(bytes/5);
		info[i].end = (i+1)*(bytes/5);
		if(4 == i)
		{
			info[i].end = bytes;
		}
		pthread_create(&tid[i],NULL,copy,info+i);
	}

	for(int i=0; i<5; i++)
	{
		pthread_join(tid[i],NULL);
	}
}
 int pthread_equal(pthread_t t1, pthread_t t2);

功能:比较两个线程ID是否相等
返回值:相等返回真,不等返回假
注意:某线程的实现线程ID不是unsigned long int类型,而是结构体类型的,因此无法使用==进行比较。

void pthread_exit(void *retval);

功能:结束当前线程
retval:线程结束时的返回值
默认创建线程可以被pthread_join函数等待结束,并回收线程资源,这种线程是非分离状态的,也可以让线程创建者无需等待,线程结束全自动释放资源,这种线程是分离状态。

int pthread_detach(pthread_t thread);

功能:设置指定的线程为分享状态
返回值:成功返回0,失败返回错误码。

int pthread_cancel(pthread_t thread);

功能:向指定的线程发送取消操作,当该线程接收到取消操作后关响应该线程就结束了。
返回值:成功返回0,失败返回错误码。

int pthread_setcancelstate(int state, int *oldstate);

功能:设置当前线程可取消状态
state:
PTHREAD_CANCEL_ENABLE 接收取消操作(默认)
PTHREAD_CANCEL_DISABLE 忽略取消操作
返回值:成功返回0,失败返回错误码。

int pthread_setcanceltype(int type, int *oldtype);

功能:设置当前线程的取消方式
type:
PTHREAD_CANCEL_DEFERRED 延迟取消
PTHREAD_CANCEL_ASYNCHRONOUS 立即取消
返回值:成功返回0,失败返回错误码。

pthread_attr_init
功能:初始化线程属性结构体
pthread_attr_destroy
功能:销毁线程属性结构体

pthread_attr_getdetachstate
功能:状态线程的分离状态
pthread_attr_setdetachstate
功能:调协线程的分离状态

pthread_attr_getguardsize
功能:获取线程栈内存的栈尾警戒区的字节数
pthread_attr_setguardsize
功能:获取线程栈内存的栈尾警戒区的字节数

pthread_attr_getschedparam
功能:获取线程的优先级
pthread_attr_setschedparam 
功能:设置线程的优先级

pthread_attr_getschedpolicy
功能:获取线程的调度策略
pthread_attr_setschedpolicy
功能:设置线程的调度策略

pthread_attr_getinheritsched
功能:获取线程的相关属性是否继承创建者线程

pthread_attr_setinheritsched
功能:设置线程的相关属性是否继承创建者线程

pthread_attr_getscope
功能:获取线程的竞争范围(系统范围、进程范围Linux系统不支持)
pthread_attr_setscope
功能:设置线程的竞争范围

pthread_attr_getstackaddr
功能:获取线程的栈内存地址
pthread_attr_setstackaddr
功能:设置线程的栈内存地址

pthread_attr_getstacksize
功能:获取线程栈内存的字节数
pthread_attr_setstacksize
功能:设置线程栈内存的字节数

pthread_attr_getstack
功能:获取栈内存的地址和字节数
pthread_attr_setstack
功能:设置栈内存的地址和字节数

猜你喜欢

转载自blog.csdn.net/perror_0/article/details/106290861