天天看點

Linux系統程式設計--程序控制 (三)

一、執行新程式

使用fork或vfork建立子程序以後,子程序調用exec函數來執行另外一個函數。

exec函數族

#include<unistd.h>
int execve(const char *path, char *const argv[], char *const envp[]);
int execv(const char *path, char *const envp[]);
int execle(const char *path, const char *arg, ...);
int execl(const char *path, const char *arg, ...);
int exevp(const char *file, char *const argv[]);
int execlp(const char *file, const char *arg, ...);
           

用來替換程序映像的程式

Linux系統程式設計--程式控制 (三)

exec函數實作程式

Linux系統程式設計--程式控制 (三)

先編譯第一個程式,生成可執行檔案:gcc -o processimage processimage.c

再編譯第二個程式,gcc -o execve execve.c

運作結果

Linux系統程式設計--程式控制 (三)
由結果可知,當調用新函數以後,原有的子程序的映像被替代,子程序永遠不會執行到printf(“process never go to here\n”)。

二、等待程序結束

僵屍程序:百度

當子程序先于父程序退出時,如果父程序沒有調用wait和waitpid函數,子程序就會進入僵死狀态,成為僵屍狀态。

#include<sys/types.h>
#include<sya/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
           

1、wait

wait函數使父程序暫停執行,直到他的一個子程序結束為止。

該函數的傳回值是終止運作的子程序的PID。

參數statloc所指向的變量存放子程序的退出碼,即子程序的main函數傳回的值或子程序中exit函數的參數。

Linux系統程式設計--程式控制 (三)

2、waitpid

wairpid用于等待某個特定程序結束,參數pid要指明等待的子程序的PID。

Linux系統程式設計--程式控制 (三)

實作代碼

Linux系統程式設計--程式控制 (三)
Linux系統程式設計--程式控制 (三)

三、setuid和aetgid

setuid設定實際使用者ID和有效使用者ID;setgid用來設定實際組ID和有效組ID

#include<stdio.h>
#include<unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
           

setuid函數遵循以下規則(setgid函數類似)

a.若程序具有root權限,則函數将實際使用者ID、有效使用者ID設定為參數uid

b.若程序不具有root權限,但uid等于實際使用者ID,則setuid隻将有效使用者ID設定為uid

c.若以上兩個條件都不滿足,則函數調用失敗,傳回-1。

四、改變程序的優先級

1、getpriority

#include<sys/resource.h>
int getpriority(int which, int who);
           

函數傳回一組程序的優先級

which和who的意義

PRIO_PROCESS:一個特定的程序,此時who的取值為程序ID

PRIO_PGRP:一個程序組的所有程序,此時who的取值為程序組ID

PRIO_USER:一個使用者擁有的所有程序,此時參數who取值為實際使用者ID

2、setpriority

#include<sys/resource.h>
int setpriority(int which, int who, int prio);
           

函數傳回指定程序的優先級,出錯傳回-1。

3、nice

#include<unistd.h>
int nice(int increment);
           

nice系統調用是getpriority和setpriority的一種組合形式,nice系統調用相當于:

int nice(int increment) 
{
    int oldpro = getpriority(PRIO_PROCESS, getpid());
    return setpriority(PRIO_PROCESS, getpid(), oldpro+increment);
}
           

繼續閱讀