一、概述
本文主要讲述了 Posix 标准的常用线程 API 接口的使用,目前 Linux/Unix 均提供了遵循 Posix 标准的线程编程 API,微软提供了自己的一套接口,acl 线程模块库根据 Posix 标准,提供了跨平台(支持 LINUX/WIN32)的线程库,接口定义及参数含义均与 Posix 的相同。如果您对 Linux 下的线程 API 比较熟悉,则当需要移植您的程序至 WIN32 平台时,只要需要在所用线程 API 前加前缀 acl_,同时将 acl 的 lib_acl.a 及相应头文件集成到您的程序中,即可将 LINUX 下线程程序移植至 WIN32 平台。
二、常用API 介绍
1)创建线程 API:pthread_create,在 acl 库中的表现形式:acl_pthread_create
/** * 创建独立的线程,使处理任务在该线程中运行,线程运行完毕,该线程的创建者 * 可以接收该线程的退出返回值 * @param tid {pthread_t*} 当线程创建成功时,该变量所指内存区域存储线程 * 的线程 ID 号 * @param attr{pthread_attr_t*} 创建线程的属性,该属性里可以设定线程的 * 堆栈大小、是否与创建线程分离等 * @param start_routine {void *(*)(void*)} 线程成功创建后开始运行的函数指针, * 该函数指针是用户应用的功能函数入口,函数的参数也由用户指定 * @param arg {void*} start 函数运行时传入的参数,该参数由用户设定 * @return {int} 线程创建是否成功,返回 0 表示成功,否则表示失败 * */ int pthread_create(pthread_t* tid, pthread_attr_t* attr, void *(*start)(void*), void *arg);
该 API 中有两个参数类型:pthread_t 和 pthread_attr_t,其中的创建线程属性的类型 pthread_attr_t 一般由下面 API 来初始化。
2)初始化/销毁线程属性 API:pthread_attr_init/pthread_attr_destroy,在 acl 库中的对应形式:acl_pthread_attr_init/acl_pthread_attr_destroy
/** * 初始化创建线程时的属性对象,该 API 会赋一些缺省值给属性对象,用户若想 * 改变属性中的某个缺省值,可以通过 pthread_attr_setxxx 之类的 API 设定 * @param attr {pthread_attr_t*} 线程属性对象的指针,该指针指向的空间 * 必须由用户自己分配 * @return {int} 成功则返回 0,否则返回非 0 值 */ int pthread_attr_init(pthread_attr_t *attr); /** * 销毁由 pthread_attr_init 创建的一些线程属性资源 * @param attr {pthread_attr_t*} 线程属性对象指针 * @return {int} 成功则返回 0,否则返回非 0 值 */ int pthread_attr_destroy(pthread_attr_t *attr);
在调用 pthread_attr_init 时,内部会对线程属性对象创建一些临时内存资源,所以当不需要线程属性时,需要调用 pthread_attr_destroy 来释放之。
下面的两个 API 可以设定创建时的一些特殊属性:
3)设定创建线程为分离状态:int pthread_attr_setdetachstate(pthread_attr_t *attr, int detached),在 acl 库中的表现形式:int acl_pthread_attr_setdetachstate(acl_pthread_attr_t *attr, int detached);
/** * 设定所创建线程是否处于分离模式,当父线程创建一个子线程时指定了所创建 * 子线程为可分离模式,则父线程不必接管子线程的退出状态,否则父线程必须 * 调用 pthread_join 来接管子线程的退出状态以避免资源泄露 * @param attr {pthread_attr_t*} 线程属性对象 * @param detached {int} 非 0 表示采用线程分离模式 * @return {int} 返回 0 表示成功,否则表示出错 */ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detached);
4)设定线程创建时线程堆栈大小属性:int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize),在 acl 库中的表现形式:int acl_pthread_attr_setstacksize(acl_pthread_attr_t *attr, size_t stacksize)。
/** * 该函数设定所创建线程的堆栈大小 * @param attr {pthread_attr_t*} 线程属性对象 * @param stacksize {size_t} 新创建线程的堆栈大小(单位为字节, * 在LINUX 下默认堆栈一般是 2MB) * @return {int} 返回 0 表示成功 */ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
5)当创建的子线程为非分离状态时父线程接管子线程退出状态:int pthread_join(pthread_t thread, void **thread_return) ,在 acl 库中的表现形式为:int acl_pthread_join(acl_pthread_t thread, void **thread_return)。
/** * 当所创建的子线程采用非分离方式创建时,则父线程应该调用本 API * 来接管子线程的退出状态,否则会造成资源泄露 * @param thread {pthread_t} 子线程的线程号 * @param thread_return {void**} 该指针地址指向子线程退出 * 前返回的内存地址 * @return {int} 返回 0 表示成功,否则表示失败 */ int pthread_join(pthread_t thread, void **thread_return);
在创建线程前通过 pthread_attr_setdetachstate API 给线程属性设定了将要创建的子线程为分离状态,还有另外一个 API 可以当子线程创建后再指定子线程为分离状态:
6)子线程创建成功后设定子线程的分离状态:int pthread_detach(pthread_t thread),在 acl 库中的表现形式为:int acl_pthread_detach(acl_pthread_t thread)。
/** * 子线程创建成功后调用本函数设定子线程为分离模式,调用本函数后, * 父线程禁止再调用 pthread_join 接管子线程的退出状态 * @param thread {pthread_t} 所创建的子线程的线程号 * @return {int} 返回 0 表示成功,否则表示失败 */ int pthread_detach(pthread_t thread);
7)线程中获得自身的线程 ID 号:pthread_t pthread_self(void),在 acl 库中的表现形式为:unsinged long acl_pthread_self(void)。
/** * 返回当前线程的线程号 * @return {pthread_t} */ pthread_t pthread_self(void);
以上介绍了有关 Posix 标准线程的一些常用 API,下面举一个简单的例子来说明上面 API 的使用。
三、例子
#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> static void *mythread_main(void *arg) { char *ptr = (char*) arg; printf("my thread id: %ld\r\n", pthread_self()); printf("arg: %s\r\n", ptr); free(ptr); /* 释放在父线程中分配的内存 */ ptr = strdup("thread exit ok"); return ptr; } int main(void) { char *name = strdup("thread_test"); pthread_t tid; pthread_attr_t attr; /* 初始化线程属性对象 */ if (pthread_attr_init(&attr) != 0) { /* 此处出错应该是内存资源不够所至 */ printf("pthread_attr_init error: %s\r\n", strerror(errno)); return 1; } /* 设定子线程的堆栈空间为 4MB */ if (pthread_attr_setstacksize(&attr, 4096000) != 0) { printf("pthread_attr_setstacksize error: %s\r\n", strerror(errno)); pthread_attr_destroy(&attr); /* 必须释放线程属性资源 */ return 1; } /* 创建子线程 */ if (pthread_create(&tid, mythread_main, name) != 0) { printf("pthread_create error: %s\r\n", strerror(errno)); pthread_attr_destroy(&attr); /* 必须释放线程属性资源 */ return 1; } printf("ok, create thread id: %ld\r\n", tid); /* 接管子线程的退出状态 */ if (pthread_join(&tid, &ptr) != 0) { printf("pthread_join error: %s\r\n", strerror(errno)); pthread_attr_destroy(&attr); /* 必须释放线程属性资源 */ return 1; } printf("child thread exit: %s\r\n", ptr); free(ptr); /* 释放在子线程分配的内存 */ pthread_attr_destroy(&attr); /* 释放线程属性资源 */ return 0; }
上述例子中,只需把 pthread_ 前添加前缀 acl_,同时包含头文件 #include "lib_acl.h",该例子便可以在 WIN32 平台下运行了。
本节暂且说这一些有关线程编程时用到的 API,下一节继续。
acl 库下载:https://sourceforge.net/projects/acl/
github: https://github.com/acl-dev/acl
相关推荐
在Linux操作系统中,多线程编程是一种常见且重要的编程模型,它允许多个执行流(线程)在一个进程中同时运行,以提高程序的并发性和资源利用率。多线程在系统开发中扮演着关键角色,特别是在需要高性能计算、实时...
在Linux系统中,多线程编程是一种常见的编程技术,它允许多个执行流在同一进程中并发运行,从而提高程序的响应速度、充分利用多核处理器资源,以及优化程序结构。本篇文章将详细探讨Linux环境下多线程编程的核心概念...
本文将对比Linux和Windows平台上的多线程编程,探讨它们的异同点。 首先,多线程编程的核心优势在于资源共享、通信效率和并行执行。在Linux和Windows系统中,多线程共享同一地址空间,减少了进程间通信(IPC)的...
在Linux系统中,多线程编程是一种常见的并发执行方式,它允许多个任务在单个进程中同时运行。这使得程序能够充分利用多核处理器的计算能力,提高系统的效率和响应速度。以下是对多线程编程的一些关键知识点的详细...
2 基本线程编程.............................................................................................................................................23 线程库.......................................
本文将深入探讨C#中的多线程编程,特别是如何利用Socket进行网络通信。C#语言是由微软公司推出的,旨在结合C++的强健性和VB的快速应用开发(RAD)特性,同时也为了应对Java的挑战。在网络编程方面,C#提供了丰富的...
本文将探讨MFC(Microsoft Foundation Classes)库中的多线程编程基础,基于问题提出、多线程概述以及Win32 API对多线程的支持。 首先,问题的提出源于一个简单的单线程程序示例。当程序中有一个耗时的操作,如在...
在Windows操作系统中,多线程编程是一种常见的技术,允许在一个进程中同时执行多个代码段,从而提升应用程序的效率和响应性。本文将详细讲解Windows多线程编程的基本概念、API使用以及线程同步策略。 首先,线程是...
在软件开发中,多线程编程是一种常见的技术,特别是在需要并发执行任务或者优化程序响应能力时。在VC(Visual C++)环境中,我们可以利用API函数或MFC(Microsoft Foundation Classes)库来实现多线程。本文将详细...
Linux的多线程编程主要依赖于POSIX线程库(Pthread),该库提供了一套丰富的API来创建、管理和同步线程。以下是从给定文件中总结的五个关键知识点,旨在帮助开发者更高效地进行多线程编程并避免潜在的问题。 1. **...
2 基本线程编程23 线程库................................................................................................................................................. 23 创建缺省线程...................
竞态条件是多线程编程中常见的问题,当多个线程访问共享资源时,如果没有适当的同步,可能会导致不可预知的结果。使用互斥锁、条件变量或信号量来保护共享资源,防止竞态条件的发生。 5. **理解条件变量的使用**:...
用线程编程是技巧性很强的且不可移植。 而在Java中却完全不同。Java的线程工具易于使用,并且像Java中的其他东西一样可以在不同的平台之间移植。这是一件好事,因为如果没有线程,那么除了最简单的applet之外,几乎...
Linux的多线程编程是开发高效并发应用的关键技术之一,特别是在服务器端软件和高性能计算领域。Pthread库作为Linux上最常用的多线程API,提供了丰富的接口来处理线程、互斥锁和条件变量等核心概念。以下是对Pthread...
常见的多线程API和用法 pthread_self函数 pthread_create函数 pthread_exit函数 pthread_join函数 pthread_detach函数 pthread_equal函数
Java提供了一套丰富的API来支持多线程编程,使得开发者可以轻松地创建和管理线程。以下是关于Java多线程实现的详细介绍。多线程是指一个程序中可以同时运行多个线程(Thread),每个线程可以看作是程序执行的独立...
第五章 Java线程编程的例子 数据结构和容器 简单的同步例子 一个网络服务器类 AsyncInputStream类 使用TCPServer和AsynclnputStream 总结 第六章 Java线程调度 线程调度概述 何时调度是重要的 调度和线程优先级 ...
- 多线程编程在Unix环境中也很常见,线程是共享同一地址空间的轻量级进程。线程库如POSIX threads(pthread)提供了创建、同步和管理线程的接口。 6. **权限和安全**: - Unix系统的权限模型包括用户ID、组ID以及...
OpenGL是另一个重要的图形API,与DirectX并行发展,尤其在专业图形和跨平台应用中更为常见。OpenGL提供了一套开放的、标准化的接口,允许开发者编写能在多种操作系统和硬件上运行的3D图形程序。 总之,显卡的性能...