線程編程常見API簡介(上)

 

1、概述編程

      本文主要講述了 Posix 標準的經常使用線程 API 接口的使用,目前 Linux/Unix 均提供了遵循 Posix 標準的線程編程 API,微軟提供了本身的一套接口,acl  線程模塊庫根據 Posix 標準,提供了跨平臺(支持 LINUX/WIN32)的線程庫,接口定義及參數含義均與 Posix 的相同。若是您對 Linux 下的線程 API 比較熟悉,則當須要移植您的程序至 WIN32 平臺時,只要須要在所用線程 API 前加前綴 acl_,同時將 acl 的 lib_acl.a 及相應頭文件集成到您的程序中,便可將 LINUX 下線程程序移植至 WIN32 平臺。函數

 

2、經常使用API 介紹spa

1)建立線程 API:pthread_create,在 acl 庫中的表現形式:acl_pthread_create.net

/**
 * 建立獨立的線程,使處理任務在該線程中運行,線程運行完畢,該線程的建立者
 * 能夠接收該線程的退出返回值
 * @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 來釋放之。code

      下面的兩個 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);blog

/**
 * 設定所建立線程是否處於分離模式,當父線程建立一個子線程時指定了所建立
 * 子線程爲可分離模式,則父線程沒必要接管子線程的退出狀態,不然父線程必須
 * 調用 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 的使用。  

3、例子

 

#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/

我的微博:http://weibo.com/zsxxsz

相關文章
相關標籤/搜索