午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

UNIX環(huán)境編程學(xué)習(xí)筆記(26)

 戴維圖書館 2018-06-28

lienhua34
2014-11-08

進(jìn)程控制三部曲中我們學(xué)習(xí)了進(jìn)程的創(chuàng)建、終止以及獲取終止?fàn)顟B(tài)等的進(jìn)程控制原語。線程的控制與進(jìn)程的控制有相似之處,在表 1中我們列出了進(jìn)程和線程相對應(yīng)的控制原語。

表 1: 進(jìn)程原語和線程原語的比較
進(jìn)程原語 線程原語 描述
fork pthread_create 創(chuàng)建新的控制流
exit pthread_exit 從現(xiàn)有的控制流中退出
waitpid pthread_join 從控制流中得到退出狀態(tài)
atexit pthread_cleanup_push 注冊在退出控制流時(shí)調(diào)用的函數(shù)
getpid pthread_self 獲取控制流的 ID
abort pthread_cancel 請求控制流的非正常退出

1 線程

每個(gè)線程都有一個(gè)線程 ID,線程只在它所屬的進(jìn)程環(huán)境中有效。線程ID 使用pthread_t 表示??梢酝ㄟ^調(diào)用pthread_self 函數(shù)獲取線程自身的線程 ID,

#include <pthread.h>

pthread_t pthread_self(void);

返回值:調(diào)用線程的線程ID

線程 ID 不一定是一個(gè)非負(fù)整數(shù),也有可能是一個(gè)結(jié)構(gòu)體。所以,要對比兩個(gè)線程是否相同,必須使用pthread_equal 函數(shù)來進(jìn)行,

#include <pthread.h>

int pthread_equal(pthread_t tid1, pthread_t tid2);

返回值:若相等則返回非0值,否則返回0

2 線程的創(chuàng)建

可以通過調(diào)用pthread_create 來創(chuàng)建新的線程,

#include <pthread.h>

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

返回值:若成功則返回0,否則返回錯(cuò)誤編碼

其中,參數(shù) tidp 用于返回成功創(chuàng)建的新線程的線程 ID。參數(shù) attr 用于定制各種不同的線程屬性,如果設(shè)置為 NULL,表示創(chuàng)建一個(gè)默認(rèn)屬性的線程。成功創(chuàng)建的新線程將從參數(shù)start_rtn 所指向的函數(shù)開始執(zhí)行,該函數(shù)接收一個(gè) void * 的參數(shù) arg,并返回一個(gè) void * 的返回值。

注意:pthread_create 失敗的時(shí)候返回的是錯(cuò)誤編碼,表示我們可以通過調(diào)用 strerror 函數(shù)來獲取具體的錯(cuò)誤信息。

下面我們來看一個(gè)創(chuàng)建新進(jìn)程的例子,

復(fù)制代碼
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>

void *
my_thread(void *arg)
{
  printf("in new thread. tid: %u\n", (unsigned int)pthread_self());
  return ((void *)0);
}

int
main(void)
{
  int err;
  pthread_t tid;

  err = pthread_create(&tid, NULL, my_thread, NULL);
  if ( err != 0) {
    printf("can't create thread: %s\n", strerror(err));
    exit(-1);
  }
  printf("in main thread: %u\n", (unsigned int)pthread_self());
  sleep(1);
  exit(0);
}
復(fù)制代碼

編譯該程序,生成并執(zhí)行文件pthread_create_demo。從下面的運(yùn)行結(jié)果,我們可以看到在 main 函數(shù)和my_thread 函數(shù)打印的線程 ID 是不一樣的。

lienhua34:demo$ gcc -o pthread_create_demo -pthread pthread_create_demo.c
lienhua34:demo$ ./pthread_create_demo
in main thread: 3076478720
in new thread. tid: 3076475712

3 線程終止

如果進(jìn)程中的任一線程調(diào)用了exit、_Exit 或_exit 函數(shù),那么整個(gè)進(jìn)程都將會終止。那如果我們只是想單獨(dú)的終止一個(gè)線程呢?有三種方式,

1. 線程從啟動例程中返回,返回值即為線程的退出碼。

2. 被同一個(gè)進(jìn)程中的其他線程取消。

3. 線程調(diào)用函數(shù)pthread_exit。

pthread_exit 函數(shù)的聲明如下,

#include <pthread.h>

void pthread_exit(void *rval_ptr);

進(jìn)程中其它線程可以通過調(diào)用pthread_join 來獲取指定線程的退出碼。

#include <pthread.h>

int pthread_join(pthread_t tid, void **rval_ptr);

返回值:若成功則返回0,否則返回錯(cuò)誤編號

pthread_join 函數(shù)會使調(diào)用線程一直阻塞,直到指定的線程終止。如果指定線程只是從它的啟動例程中返回,rval_ptr 將包含返回碼。如果線程被取消,由rval_ptr 指定的內(nèi)存單元將被置為PTHREAD_CANCELED。

下面我們來看一個(gè)線程終止的例子,

pthread_exit_demo.c

編譯該程序,生成并執(zhí)行文件pthread_exit_demo,

復(fù)制代碼
lienhua34:demo$ gcc -o pthread_exit_demo -pthread pthread_exit_demo.c
lienhua34:demo$ ./pthread_exit_demo
in thread 1
in thread 2
thread 1 exit code: 1
thread 2 exit code: 2
復(fù)制代碼

(done)

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多