线程编程常见API简介(上)
2019獨角獸企業(yè)重金招聘Python工程師標準>>>
?
一、概述
? ? ? 本文主要講述了 Posix 標準的常用線程 API 接口的使用,目前 Linux/Unix 均提供了遵循 Posix 標準的線程編程 API,微軟提供了自己的一套接口,acl ?線程模塊庫根據(jù) Posix 標準,提供了跨平臺(支持 LINUX/WIN32)的線程庫,接口定義及參數(shù)含義均與 Posix 的相同。如果您對 Linux 下的線程 API 比較熟悉,則當需要移植您的程序至 WIN32 平臺時,只要需要在所用線程 API 前加前綴 acl_,同時將 acl 的 lib_acl.a 及相應頭文件集成到您的程序中,即可將 LINUX 下線程程序移植至 WIN32 平臺。
?
二、常用API 介紹
1)創(chuàng)建線程 API:pthread_create,在 acl 庫中的表現(xiàn)形式:acl_pthread_create
/*** 創(chuàng)建獨立的線程,使處理任務在該線程中運行,線程運行完畢,該線程的創(chuàng)建者* 可以接收該線程的退出返回值* @param tid {pthread_t*} 當線程創(chuàng)建成功時,該變量所指內存區(qū)域存儲線程* 的線程 ID 號* @param attr{pthread_attr_t*} 創(chuàng)建線程的屬性,該屬性里可以設定線程的* 堆棧大小、是否與創(chuàng)建線程分離等* @param start_routine {void *(*)(void*)} 線程成功創(chuàng)建后開始運行的函數(shù)指針,* 該函數(shù)指針是用戶應用的功能函數(shù)入口,函數(shù)的參數(shù)也由用戶指定* @param arg {void*} start 函數(shù)運行時傳入的參數(shù),該參數(shù)由用戶設定* @return {int} 線程創(chuàng)建是否成功,返回 0 表示成功,否則表示失敗**/ int pthread_create(pthread_t* tid, pthread_attr_t* attr, void *(*start)(void*), void *arg);?? ? ??該 API 中有兩個參數(shù)類型:pthread_t 和 pthread_attr_t,其中的創(chuàng)建線程屬性的類型 pthread_attr_t 一般由下面 API 來初始化。
2)初始化/銷毀線程屬性 API:pthread_attr_init/pthread_attr_destroy,在 acl 庫中的對應形式:acl_pthread_attr_init/acl_pthread_attr_destroy
/*** 初始化創(chuàng)建線程時的屬性對象,該 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 創(chuàng)建的一些線程屬性資源* @param attr {pthread_attr_t*} 線程屬性對象指針* @return {int} 成功則返回 0,否則返回非 0 值*/ int pthread_attr_destroy(pthread_attr_t *attr);? ? ? 在調用 pthread_attr_init 時,內部會對線程屬性對象創(chuàng)建一些臨時內存資源,所以當不需要線程屬性時,需要調用 pthread_attr_destroy 來釋放之。
? ? ? 下面的兩個 API 可以設定創(chuàng)建時的一些特殊屬性:
3)設定創(chuàng)建線程為分離狀態(tài):int pthread_attr_setdetachstate(pthread_attr_t *attr, int detached),在 acl 庫中的表現(xiàn)形式:int acl_pthread_attr_setdetachstate(acl_pthread_attr_t *attr, int detached);
/*** 設定所創(chuàng)建線程是否處于分離模式,當父線程創(chuàng)建一個子線程時指定了所創(chuàng)建* 子線程為可分離模式,則父線程不必接管子線程的退出狀態(tài),否則父線程必須* 調用 pthread_join 來接管子線程的退出狀態(tài)以避免資源泄露* @param attr {pthread_attr_t*} 線程屬性對象* @param detached {int} 非 0 表示采用線程分離模式* @return {int} 返回 0 表示成功,否則表示出錯*/ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detached);?4)設定線程創(chuàng)建時線程堆棧大小屬性:int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize),在 acl 庫中的表現(xiàn)形式:int acl_pthread_attr_setstacksize(acl_pthread_attr_t *attr, size_t stacksize)。
/*** 該函數(shù)設定所創(chuàng)建線程的堆棧大小* @param attr {pthread_attr_t*} 線程屬性對象* @param stacksize {size_t} 新創(chuàng)建線程的堆棧大小(單位為字節(jié),* 在LINUX 下默認堆棧一般是 2MB)* @return {int} 返回 0 表示成功*/ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);?5)當創(chuàng)建的子線程為非分離狀態(tài)時父線程接管子線程退出狀態(tài):int pthread_join(pthread_t thread, void **thread_return)?,在 acl 庫中的表現(xiàn)形式為:int acl_pthread_join(acl_pthread_t thread, void **thread_return)。
/*** 當所創(chuàng)建的子線程采用非分離方式創(chuàng)建時,則父線程應該調用本 API* 來接管子線程的退出狀態(tài),否則會造成資源泄露* @param thread {pthread_t} 子線程的線程號* @param thread_return {void**} 該指針地址指向子線程退出* 前返回的內存地址* @return {int} 返回 0 表示成功,否則表示失敗*/ int pthread_join(pthread_t thread, void **thread_return);? ? ? ?在創(chuàng)建線程前通過?pthread_attr_setdetachstate API 給線程屬性設定了將要創(chuàng)建的子線程為分離狀態(tài),還有另外一個 API 可以當子線程創(chuàng)建后再指定子線程為分離狀態(tài):
?6)子線程創(chuàng)建成功后設定子線程的分離狀態(tài):int pthread_detach(pthread_t thread),在 acl 庫中的表現(xiàn)形式為:int acl_pthread_detach(acl_pthread_t thread)。
/*** 子線程創(chuàng)建成功后調用本函數(shù)設定子線程為分離模式,調用本函數(shù)后,* 父線程禁止再調用 pthread_join 接管子線程的退出狀態(tài)* @param thread {pthread_t} 所創(chuàng)建的子線程的線程號* @return {int} 返回 0 表示成功,否則表示失敗*/ int pthread_detach(pthread_t thread);?7)線程中獲得自身的線程 ID 號:pthread_t pthread_self(void),在 acl 庫中的表現(xiàn)形式為: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;}/* 創(chuàng)建子線程 */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);/* 接管子線程的退出狀態(tài) */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 平臺下運行了。
? ? ? 本節(jié)暫且說這一些有關線程編程時用到的 API,下一節(jié)繼續(xù)。
本文地址
acl 庫下載:https://sourceforge.net/projects/acl/
個人微博:http://weibo.com/zsxxsz
轉載于:https://my.oschina.net/u/568966/blog/309527
總結
以上是生活随笔為你收集整理的线程编程常见API简介(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 彻底解决PHP Session不过期以及
- 下一篇: 博弈论题目总结