進程線程等學習筆記

總共分爲12部分分別是:進程、線程、消息隊列、信號量集、共享內存、PGSQL編程、MYSQL編程、網絡編程、文件訪問、標準I/O、系統數據文件和信息、信號
(一) 進程
1. 進程ID爲0的進程通常是調度進程,常常被稱爲交換進程
進程ID爲1的進程通常是init進程,在自舉過程結束時由內核調用
進程ID爲2的進程頁守護進程,負責支持虛擬存儲系統的分頁操作
2. pid_t getpid( void ); 返回值:調用進程的進程ID #include <unistd.h>
3. pid_t getppid( void ); 返回值:調用進程的父進程ID
4. uid_t getuid( void ); 返回值:調用進程的實際用戶ID
5. uid_t geteuid( void ); 返回值:調用進程的有效用戶ID
6. gid_t getgid( void ); 返回值:調用進程的實際組ID
7. gid_t getegid( void ); 返回值:調用進程的有效組ID
8. pid_t fork( void );創建子進程,返回值:子進程返回0,父進程返回子進程ID,出錯-1
9. #include<sys/wait.h> pid_t wait(int *statloc);//statloc 保存進程終止狀態的指針
10. #include<sys/wait.h>pid_t waitpid(pid_t pid,int *statloc,int options);
pid ==-1 等待任一子進程
pid >0 等待其子進程ID與pid相等的子進程
pid == 0 等待其組ID等於調用進程組ID的任一子進程
pid <-1 等待其組ID等於pid絕對值的任一子進程
options:
WCONTINUED 若實現支持作業控制,那麼由pid指定的任一子進程在暫停後已經繼續,但其狀態尚未報告,則返回其狀態
WNOHANG 若由pid指定的子進程並不是立即可用的,則waitpid阻塞,此時其返回0
WUNTRACED 若實現支持作業控制,而由pid指定的任一子進程已處於暫停狀態,並且其狀態自暫停以來還未報告過,則返回其狀態
11.#include<unistd.h> int setuid(uid_t uid); 設置實際實際用戶ID和有效用戶ID;
int setgid(gid_t gid); 設置實際組ID和有效組ID;成功返回0,錯誤-1
12.#include<stdlib.h>int system(const char *cmdstring)
system返回值如下
-1出現錯誤
0調用成功但是沒有出現子進程
>0 成功退出的子進程的id
(二)線程
1. #include<thread.h> int pthread_equal(pthread_t tid1, pthread_t tid2);
//相等返回非0,否則返回0
2. pthread_t pthread_self(void);返回調用線程的ID
3. int pthread_create(pthread_t *restrict tidp,
const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg) ;
創建線程:成功返回0,否則返回錯誤編號
4. void pthread_exit(void *rval_ptr);//終止線程
5. int pthread_join(pthread_t thread, void **rval_ptr);
//自動線程置於分離狀態,以恢復資源。成功返回0,否則返回錯誤編號
6. int pthread_cancel(pthread_t tid);
//請求取消同一進程中的其他線程;成功返回0,否則返回錯誤編號
7. void pthread_cleanup_push(void (*rtn)(void *), void *arg);
//建立線程清理處理程序
8. void pthread_cleanup_pop(int execute);//調用建立的清理處理程序
9. int pthread_detach(pthread_t tid);//使線程進入分離狀態,已分離也不出錯
10.int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_nutexattr_t *restrict attr)//初始化互斥量;成功0,失敗返回錯誤編號
11.int pthread_mutex_destroy(pthread_mutex_t *mutex);
//若有調用malloc動態分配內存則用該函數釋放;成功0,失敗返回錯誤編號
12.int pthread_mutex_lock(pthread_mutex_t *mutex);//鎖住互斥量
int pthread_mutex_trylock(pthread_mutex_t *mutex);//嘗試上鎖
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解鎖
成功返回0,否則返回錯誤編號
13.int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr)//初始化讀寫鎖
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);//釋放資源,在釋放內存之前使用
成功返回0,否則返回錯誤編號
14.int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//在讀模式下鎖定讀寫鎖
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//在寫模式下鎖定讀寫鎖
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//鎖住讀寫鎖
15.int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);//嘗試在讀模式下鎖定讀寫鎖
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);//嘗試在寫模式下鎖定讀寫鎖
成功返回0,否則返回錯誤編號
16.int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t * restrict attr)
//初始化條件變量
int pthread_cond_destroy(pthread_cond_t *cond);//去除初始化條件變量
成功返回0,否則返回錯誤編號
17.int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex,
const struct timespec *restrict timeout);
//等待條件變爲真,如果在給定的時間內條件不能滿足,那麼會生成一個代表出錯碼的返回變量 ;成功返回0,錯誤返回錯誤編號
18.int pthread_cond_signal(pthread_cond_t *cond);//喚醒等待該條件的某個線程
int pthread_cond_broadcast(pthread_cond_t *cond)//喚醒等待該條件的所有線程
19.int pthread_attr_init(pthread_attr_t *attr);//初始化線程屬性
int pthread_attr_destroy(pthread_attr_t *attr);//釋放內存空間(動態分配時調用)
成功返回0,否則返回錯誤編號
20.int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);
//獲取線程的分離狀態
int pthread_attr_setdetachstate(const pthread_attr_t *restrict attr, int detachstate);
//設置分離狀態 PTHREAD_CREATE_DETACHED:以分離狀態啓動線程
PTHREAD_CREATE_JOINABLE:正常啓動線程,應用程序可以獲取線程的終止狀態
成功返回0,否則返回錯誤編號
21.int pthread_attr_getstack(const pthread_attr_t *restrict attr,void **restrict stackaddr, size_t *restrict stacksize);//獲取線程的棧位置
int pthread_attr_setstack(const pthread_attr_t *attr, void *stackaddr, size_t *stacksize)
//設置新建線程的棧位置 ;成功返回0,否則返回錯誤編號
(三)消息隊列
1.每個隊列都有一個msqid_ds結構與之相關聯:
struct msqid_ds{
struct ipc_perm msg_perm;
msgqnum_t msg_qnum; //消息的數量
msglen_t msg_qbytes; //最大消息的長度
pid_t msg_lspid; //最後一個發送到消息隊列的進程ID
pid_t msg_lrpid; //最後一個讀取消息的進程ID
time_t msg_stime; //最後一次發送到消息隊列的時間
time_t msg_rtime; //最後一次讀取消息的時間
time_t msg_ctime; //最後一次改變的時間



};
struct ipc_perm{
uid_t uid;//擁有者有效的用戶ID
gid_t gid;//擁有者有效的組ID
uid_t cuid;//創建者有效的用戶ID
uid_t cgid;//創建者有效的組ID
mode_t mode; //權限


}
2.#include <sys/msg.h> int msgget(key_t key, int flag);
//打開一個現存的隊列或創建一個新隊列;成功返回0,出錯返回-1
3.int msgctl(int msqid, int cmd, struct msqid_ds *buf);//對消息隊列執行多種操作
cmd 可選:
IPC_STAT 取此消息隊列的msqid_ds結構,並將它放在buf指向的結構
IPC_SET:按由buf指向結構中的值,設置與此隊列相關結構中的下列四個字段:msg_perm.uid,msg_perm.gid,msg_perm.mode和msg_qbytes.此命令只有下列兩種進程才能執行(1)其有效用戶ID等於msg_perm.cuid或msg_perm.uid;(2)具有超級用戶特權的進程
IPC_RMID:從系統中刪除消息隊列以及仍在該隊列中的所有數據。
成功返回0,失敗返回-1
4.int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag)//發送消息到消息隊列中
成功返回0, 不成功返回-1並設置errno,錯誤碼:
EACCES 對調用程序來說,調用被否定
EAGAIN 操作會阻塞進程,但(msgflg & IPC_NOWAIT) != 0
EIDRM msqid已經從系統中刪除了
EINTR 函數被信號中斷
EINVAL 參數msqid無效,消息類型<1,或者msgsz越界了
flag可以指定爲IPC_NOWAIT 則不會阻塞直接返回EAGAIN
注:參數msgp指向用戶定義的緩衝區,他是如下的結構
struct mymsg
{
long mtypes; 消息類型
char *mtext; 消息文本
}mymsg_t
5.ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);//讀取消息
成功則返回消息的數據部分的長度,出錯則返回-1
type: type==0返回隊列中的第一個消息
type>0 返回隊列中消息類型爲type的第一個消息
type<0返回隊列中消息類型值小於或等於type絕對值的消息(多個取類型值最小的)
(四) 信號量
1. 內核爲每個信號量集合設置了一個semid_ds結構:
struct demid_ds{
struct ipc_perm sem_perm;
unsigned short sem_nsems; //信號量的個數
time_t sem_otime; //上一次semop的時間
time_t sem_ctime;//上一次change的時間

    。
 };
2#include<sys/sem.h>. int semget(key_t key, int nsems, int flag);//創建信號量
成功返回一個對應於信號量集標識符的非負整數,不成功返回-1並設置errno,錯誤碼:
EACCES 存在key的信號量,但沒有授予權限
EEXIST 存在key的信號量,但是
( (semflg & IPC_CREATE) && (semflg & IPC_EXCL) ) != 0
EINVAL nsems <= 0或者大於系統的限制,或者nsems與信號量集的大小不符
ENOENT 不存在key的信號量,而且(semflg & IPC_CTEATE) == 0
ENOSPC 要超出系統範圍內對信號量的限制了
功能:
函數返回與參數key相關的信號量集標識符。
如果鍵值爲IPC_PRIVATE,或者semflg&IPC_CREAT非零且沒有信號量集或標識符關聯於key,那麼函數就創建標識符及與之相關的信號量集。
參數nsems指定了集合中信號量元素的個數,可用0到nsems-1的整數來引用信號量集合中的單個信號量元素。
參數semflg指定信號量集的優先級,權限的設置與文件權限設置相同,並可以通過semclt來修改權限值,在使用信號量元素之前,應該用semctl對其進行初始化。
注意:
函數如果試圖創建一個已經存在的信號量集,如果semflg值中包含了IPC_CREAT和IPC_EXCL,則失敗並設置errno爲EEXIST;否則返回一個已經存在的信號量集的句柄。
3.int semctl(int semid, int semnum, int cmd, …);//信號量控制
如果成功返回一個非負的值,具體返回值取決於cmd的值。
cmd值GETVAL、GETPID、GETNCNT和GETZCNT使semctl返回與cmd相關的值。
如果成功,所有其它的cmd返回0。
如果不成功semctl返回-1並設置errno,必須檢測的錯誤碼:
EACCES 對調用程序來說,操作被否定
EINVAL semid的值或cmd的值無效,或者semnum的值爲負或者太大
EPERM cmd的值爲IPC_RMID或IPC_SET,且調用程序沒有所要求的特權
ERANGE cmd爲SETVAL或SETALL,而且要設置的值越界了
功能:
函數semctl爲信號量集semid的semnum個元素提供了控制操作。參數cmd指定了操作類型,第四個參數arg可選,是否使用取決於cmd的值。
cmd的值:
GETALL 在arg.array中返回信號量集的值
GETVAL 返回一個特定信號量元素的值
GETPID 返回最後一個操縱元素的進程的進程ID
GETNCNT 返回等待元素增加的進程的個數
GETZCNT 返回等待元素變成零的進程的個數
IPC_RMID 刪除semid標識的信號量集
IPC_SET 設置來之arg.buf的信號量集的權限
IPC_STAT 將信號量集semid的semid_ds結構成員拷貝到arg.buf中
SETALL 用arg.array來設置信號量集的值
SETVAL 將一個特定的信號量元素的值設定爲arg.val
其中有幾個命令需要一個arg參數來讀取或存儲結構
參數arg的類型爲union semun,必須要定義這個類型的數據:
union semum
{
int val
struct semid_ds *buf;
unsigned short *array;
}arg;
4. int semop(int semid, struct sembuf *sops, size_t nsops);//信號量的操作
成功返回0,不成功返回-1並設置errno,必須檢測的錯誤碼:
E2BIG nsops的值太大
EACCES 對調用程序來說,操作被否定
EAGAIN 操作會阻塞進程但是(sem_flg&IPC_NOWAIT)!= 0
EFBIG 某一個sops條目的sem_num值小於0,或大於信號量集中元素的數目
EIDRM 信號量集標識符semid已經從系統中刪除了
EINTR semop被信號中斷
EINVAL semid的值無效,或者請求做SEM_UNDO操作的獨立信號量集的數量
超出了限制
ENOSPC 已經超出了對請求SEM_UNDO的進程數的限制
ERANGE 操作會造成semval或semadj值得溢出
功能:
semop函數在單個信號量集上原子的執行sops數組中指定的所有操作。如果其中任何一個單獨的元素操作會使進程阻塞,進程就會阻塞而不會執行任何操作。
說明:
結構struct sembuf指定了一個信號量元素操作,包含下列成員。
short sem_num 信號量元素的數量(信號量元素在信號量集中的序號)
short sem_op 要執行的特定元素操作
short sem_flg 爲操作指定選項的標誌符
sem_op如果是大於零的整數,semop就將這個值與sem_num號信號量元素相加,並喚醒所有等待該元素增加的進程。
如果爲零,且信號量元素值不爲0,semop就會阻塞調用進程(進程在等待0),並增加等待那個信號量元素值變爲零的進程計數。
如果sem_op爲負數,那麼,如果結果不能爲負的話,semop就將sem_op值添加到相應的信號量元素值上去。如果操作可能會使元素值爲負,semop就將進程阻塞在使信號量元素值增加的事件上。如果結果值爲0,那麼semop就喚醒等待0的進程。
(五)共享內存
1.內核爲每個共享內存設置了一個 shmid_ds結構,它的成員如下:
Struct shmid_ds{
struct ipc_perm shm_perm; //操作權限結構
size_t shm_segsz; //用字節表示的段的長度
pid_t shm_lpid; //最後一個操作的進程ID
pid_t shm_cpid; //創建者的進程ID
shmatt_t shm_nattch //當前連接的進程數量
time_t shm_atime; //最後一次調用shmat的時間
time_t shm_dtime; //最後一次調用shmdt的時間
time_t shm_ctime; //最後一次調用shmtl的時間


}
2.include<sys/shm.h> int shmget(key_t key, size_t size, int flag);//創建共享內存
size指的是共享內存段的格式n*sizeof(int)則共享內存段將用來存儲int類型數據n個
成功返回一個對應於共享內存段標識符的非負整數,不成功返回-1並設置errno,錯誤碼:
EACCES key的共享標識符存在,但沒有授予相關的權限
EEXIST key的共享標識符存在,但((shmflg&IPC_CREAT) && (shmflg&IPC_EXCL)!=0
EINVAL 要創建共享內存段,但size是無效的
EINVAL 沒有共享內存段要創建,但size與系統設置的限制或與key所代表的共享段的長度不相符
ENOENT key的共享內存表示符不存在,但(shmflg&IPC_CREAT)== 0
ENOMEM 沒有足夠的內存空間來創建指定的共享內存段
ENOSPC 要超出系統範圍內對共享標識符的限制了
功能:
shmget函數返回一個與參數key相關的共享內存段標識符。
如果鍵位IPC_CREAT或者shmflg&IPC_CREAT非零,而且沒有共享內存段或標識符與key相關聯,函數就創建這個段,共享內存段被初始化爲零。
3. int shmctl(int shmid, int cmd, struct shmid_ds *buf);//共享內存的控制
成功返回0,不成功返回-1並設置errno,錯誤碼:
EACCES cmd爲IPC_STAT,但是調用程序沒有讀權限
EINVAL shmid或cmd的值無效
EPERM cmd爲IPC_RMID或IPC_SET,調用程序沒有正確的權限
cmd值:
IPC_RMID 刪除共享內存段,並銷燬相應的shmid_ds
IPC_SET 用buf中的值來設置共享內存段shmid的字段值
IPC_STAT 將共享內存段shmid中的當前值拷貝到buf中去
IPC_LOCK 將共享內存段鎖定在內存中(只有超級用戶可以執行)
IPC_UNLOCK 解鎖共享內存
4.void *shmat(int shmid, const void *shmaddr, int shmflg);//共享內存段的連接
成功返回內存段的起始地址,不成功shmat返回-1並設置errno,必須檢測的錯誤碼:
EACCES 調用程序的操作權限別否定
EINVLA shmid和shmaddr的無效
EMFILE 連接到進程上的共享內存段的樹木超出了限制
ENOMEM 進程數據空間不足以容納共享內存段
功能:
函數將shmid指定的共享內存段連接到調用進程的地址空間,併爲shmid增加shm_nattch的值。
如果shmaddr爲0,則此段連接到由內核選擇的第一個可用的地址上
如果shmaddr非0,並且沒有指定SHM_RND,則此段連接到addr所指定的地址上
如果shmaddr非0,並且指定了SHM_RND,則此段連接到(addr-(addr mod ulus SHMLBA))所表示的地址上。
5. int shmdt(const void *shmaddr);//分離共享內存
成功返回0,不成功返回-1並設置errno,錯誤碼:
EINVAL shmaddr不對應於共享內存段的起始地址
功能:
用完一個共享內存,調用其來分離共享內存段,並對shm_nattch進行減操作。
最後一個分離共享內存段的進程應該通過調用shmctl來釋放共享內存段
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章