### 關于線程的一些描述
- 共享數據方便
- 一個進程中多個線程可以同時運行
- POSIX線程庫,pthread,編譯的時候需要加上-lphread
- 所有線程共享相同的全局和堆變量,但每個線程都有自己存放局部變量的私有棧
- 線程不安全,多線程之間相互影響共享變量,需要互斥鎖
- 一個線程出問題,會危及到其他線程,即不穩定
- 線程避免使用信號
### pthread_create
創建線程并運行
```c
// returns 0 on success, or a positice error number on error
#include <pthread.h>
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
```
- 線程函數返回的類型為void *
### pthread_exit
終止進程
```c
#include <pthread.h>
pthread_exit(void *retval)
```
- 任意線程調用exit()或主線程執行了return語句都會導致進程中所有線程立即終止
- 其返回值可以由另一線程通過pthread_join()來獲取
- 參數retval指定了線程的返回值,指向的內容不應分配于線程棧中
### pthread_self
獲取當前線程ID
```c
include <pthread.h>
pthread_t pthread_self(void);
```
### pthread_join
等待線程結束
```c
// returns 0 on success, or a positive error number on error
#include <pthread.h>
pthread_join(pthread_t thread, void **retval);
```
- retval 保存線程終止時返回值的拷貝,即線程調用return或pthread_exit時所指定的值
- 沒有調用pthread_join將產生僵尸線程,除非是分離狀態的線程(pthread_detach)
### pthread_detach
將線程標識為分離狀態,這樣線程終止能夠自動清理和移除,不需要調用pthread_join來獲取其返回狀態
```c
// returns 0 on success, or a positive error number on error
#include <pthread.h>
pthread_detach(pthread_t thread);
```
### 互斥量mutex(mutual exclusion)
- 互斥鎖必須對所有線程可見,即互斥鎖是一個全局變量,互斥鎖用在需要修改共享變量位置
- 類型為pthread_mutex_t
- 靜態分配的互斥量,PTHREAD_MUTEX_INITIALIZER
- 動態分配的互斥量,pthread_mutext_init
```c
pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&a_lock); // 加鎖
pthread_mutex_unlock(&a_lock); // 解鎖
```
### 動態初始化互斥量
```c
// returns 0 on success, or a positive error number on error
#include <pthread.h>
pthread_mutex_init(pthread_mutex_t *mutext, const pthread_mutexattr_t *attr)
```
動態分配的互斥量需要通過pthread_mutex_destroy
```c
// returns 0 on success, or a positive error number on error
#include <pthread.h>
pthread_mutex_destory(pthread_mutex_t *mutex)
```
### 互斥量類型
```c
pthread_mutexattr_settype(pthread_mutexattr *attr, type)
```
type類型如下:
- PTHREAD_MUTEX_NORMAL 互斥量不具有死鎖檢測功能
- PTHREAD_MUTEX_ERRORCHECK 對此類互斥量的所有操作都會執行錯誤檢查,運行慢
- PTHREAD_MUTEX_RECURSIVE 遞歸互斥量維護一個鎖計數器
### 互斥量的死鎖
一般出現在線程有多個互斥量
- 確定互斥量的層級關系
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#define NUM_SIZE 20
int num = 2000000;
pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;
void *modify_num()
{
pthread_mutex_lock(&a_lock);
for (int i = 0; i < 100000; ++i)
{
num = num - 1;
}
pthread_mutex_unlock(&a_lock);
printf("nun=%d\n", num);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t threads[NUM_SIZE];
for (int i = 0; i < NUM_SIZE; ++i)
{
if (pthread_create(&threads[i], NULL, modify_num, NULL) == -1)
{
printf("%s\n", "pthread create failed");
exit(1);
}
}
void *result;
for (int i = 0; i < NUM_SIZE; ++i)
{
if (pthread_join(threads[i], &result) == -1)
{
printf("%s\n", "pthread join failed");
}
}
printf("剩余%d\n", num);
return 0;
}
```
### 參考
- 嗨翻C語言
- php
- 編譯安裝
- 基本概念
- 垃圾回收機制
- 生命周期
- zval底層實現
- c擴展開發
- gdb調試工具
- 自定義擴展簡單demo
- 鉤子函數
- 讀取php.ini配置
- 數組
- 函數
- 類
- yaf擴展底層源碼
- swoole擴展底層源碼
- memoryGlobal內存池
- swoole協程使用記錄
- 單點登錄sso原理
- compser使用
- session實現機制
- c & linux
- gcc
- 指針
- 結構體,聯合和位字段
- 宏定義井號說明
- printf家族函數和可變參數
- 共享函數
- 靜態庫和動態庫
- makefile自動化構建
- 信號一
- 信號二
- inotify監控文件事件
- socket編程
- 簡介
- UNIX DOMAIN
- Internet DOMAIN
- TCP/IP
- 文件IO多路復用
- 內存管理
- 進程組,會話和控制終端
- daemon守護進程
- 多進程
- 多線程
- 常用進制轉換
- go
- 入門知識
- 字節和整數裝換
- python
- redis
- 應用場景
- 消息隊列
- 熱點數據
- 掃碼登錄
- 訂閱發布
- 次數限制
- 搶購超賣
- 持久化機制
- mysql
- 工作流程
- MyISAM和InnoDB區別
- 用戶和權限管理
- 執行計劃
- sql優化
- 事務和鎖
- 慢查詢日志
- case...when...then...end用法
- sql
- 參考
- linux
- 內核參數優化
- 防火墻設置
- docker
- docker入門知識
- 算法
- 多維數組合
- DFA算法
- 紅包金額分配