1. 程式人生 > >linux c程式設計 程序程式設計(整理)

linux c程式設計 程序程式設計(整理)

(程式碼來自《嵌入式linux應用程式開發標準教程》)

概覽:

第一部份:程序簡介

第二部份:程序控制  :命令  函式

第三部份:程序例項:  多程序  守護程序

第四部份:附加材料

linux 程序控制函式大全    

第一部份:程序簡介

程序是Linux系統的基本排程和管理資源的單位,它是通過程序控制塊來描述的。程序控制塊包含了程序的描述資訊、控制資訊以及資源資訊,它是程序的一個靜態描述。在Linux中,程序控制塊中的每一項都是一個task_struct結構。 
在Linux中最主要的程序標識有程序號(PID,Process Idenity Number)和它的父程序號(PPID,parent process ID)。其中PID惟一地標識一個程序。PID和PPID都是非零的正整數。
在Linux中獲得當前程序的PID和PPID的系統呼叫函式為getpid()和getppid(),通常程式獲得當前程序的PID和PPID之後,可以將其寫入日誌檔案以做備份。 
另外,程序標識還有使用者和使用者組標識、程序時間、資源利用情況等 

程序是Linux系統的基本排程和管理資源的單位,它是通過程序控制塊來描述的。程序控制塊包含了程序的描述資訊、控制資訊以及資源資訊,它是程序的一個靜態描述。在Linux中,程序控制塊中的每一項都是一個task_struct結構。 
在Linux中最主要的程序標識有程序號(PID,Process Idenity Number)和它的父程序號(PPID,parent process ID)。其中PID惟一地標識一個程序。PID和PPID都是非零的正整數。
在Linux中獲得當前程序的PID和PPID的系統呼叫函式為getpid()和getppid(),通常程式獲得當前程序的PID和PPID之後,可以將其寫入日誌檔案以做備份。 
另外,程序標識還有使用者和使用者組標識、程序時間、資源利用情況等 

程序三種狀態  就緒 執行 等待

第二部份:程序控制

常用命令

  • at命令:在指定時刻執行指定的命令序列

格式:

at [-V] [-q x] [-f file] [-m] time

atq [-V] [-q x]

atrm [-V] [-q x] job…

batch [-V] [-f file] [-m]

  • bg命令:使一個被掛起的程序在後臺執行

格式:bg 該命令無引數。

先使用組合鍵"Ctrl+Z"。然後使用bg命令。如果想直接把這個命令放在後臺執行,可以在命令後使用"&"符號:

#du -a / | sort -rn > /tmp/du.sorted &

  • fg命令:使一個被掛起的程序在前臺執行

格式:fg -[job-spec]

  • jobs命令:顯示後臺任務的執行情況

格式:jobs [選項] [jobspec…]

  • kill命令:終止一個程序

格式:kill [-s signal |-p] [-a]pid

  • crontab命令:用於安裝、刪除或者列出用於驅動cron後臺程序的任務表。然後,該配置由cron守護程序在設定的時間執行

格式:crontab [-u user] 檔案

  • ps命令:檢視系統中程序的狀態

格式:ps [選項],如ps aux

  • pstree命令:列出當前的程序,以及它們的樹狀結構

格式:pstree [選項] [pid|user]

  • top命令:顯示系統當前的程序狀況

格式:top [選項]

說明:top命令和ps命令的基本作用是相同的,都顯示系統當前的程序狀況。但是top是一個動態顯示過程,即可以通過使用者按鍵來不斷重新整理當前狀態。

  • nice命令:改變程式執行的優先權等級

格式:nice [-n <優先等級>][--help][--version][命令]

說明:應用程式優先權值的範圍從-20~19,數字越小,優先權就越高。一般情況下,普通應用程式的優先權值(CPU使用權值)都是0,如果讓常用程式擁有較高的優先權等級,自然啟動和執行速度都會快些。需要注意的是普通使用者只能在0~19之間調整應用程式的優先權值,只有超級使用者有權調整更高的優先權值(從-20~19)。

  • renice命令:允許使用者修改一個正在執行的程序的優先權

格式:renice priority [ [ -p ] pids ] [ [ -g ] pgrps ] [ [ -u ] users ]

說明:renice命令可重新調整正在執行的程式的優先權等級。預設是以程式識別碼指定程式,調整其優先權,也可以指定程式群組或使用者名稱稱調整優先權等級,並修改所有隸屬於該程式群組或使用者的程式的優先權。等級範圍從-20~19,只有超級使用者可以改變其他使用者程式的優先權和設定負數等級。普通使用者只能對自己所有的程序使用renice命令。

  • sleep命令:使程序暫停執行一段時間

格式:sleep number [選項]

  • nohup命令:使用者退出系統之後繼續工作

格式:nohup命令

說明:一般退出Linux系統時,會把所有的程式全部結束掉,包括那些後臺程式。但有時候,例如,使用者正在下載一個很大的檔案,但是你因下班或有事需要先退出系統,希望退出系統時程式還能繼續執行。這時,我們就可以使用nohup命令使程序在使用者退出後仍繼續執行。同時這些程序都在後臺執行(命令放到後臺執行,nohup必須與&操作同時使用),結果則會寫到使用者自己的目錄下的nohup.out檔案裡。

  • pgrep命令:查詢當前執行的程序,並列出匹配給定條件的程序的pid,所有的條件都必須匹配才會被列出

格式:pgrep [選項][程式名]

  • chkconfig命令: 檢查,設定系統的各種服務

格式:chkconfig [--add][--del][--list][系統服務]


獲取程序id

Linux程序的管理 <一>獲取程序資訊函式

程序又稱任務,是一個動態的使用系統資源、處於活動狀態的應用程式。
程序的管理由程序控制塊PCB、程序排程、中斷管理、任務佇列等組成,它是linux檔案系統、儲存管理、裝置管理和驅動程式的基礎。
程序控制塊PCB中包含了程序的所有資訊,主要包括程序PID、程序所佔有的記憶體區域、檔案描述符和程序環境等資訊。
他用task_struct的資料結構表示,存在於include/linux/sch.h

程序狀態及轉換
#define TASK_RUNNING 0 //執行狀態
#define TASK_INTERRUPTIBLE 1 //等待狀態(可被中斷)
#define TASK_UNINTERRUPTIBLE 2  //等待狀態(不可被中斷)
#define TASK_STOPPED 4  //停止狀態
#define TASK_ZOMBIE 8  //睡眠狀態
#define TASK_DEAD 16  //僵死狀態

程序的基本操作,六大類:
1.獲取程序資訊函式:主要通過讀取程序控制塊PCB中的資訊。
(1)getpid()
功能:用來獲取目前程序的程序標識。
定義函式:pid_t getpid(void)
返回值:返回當前程序的程序識別號。
標頭檔案:#include <unistd.h>

(2)getppid()
功能:用來獲取目前程序的父程序標識。
定義函式:pid_t getppid(void)
返回值:返回當前程序的父程序識別號。
標頭檔案:#include <unistd.h>

(3)getpgid()
功能:用來獲得引數pid指令程序所屬於的組識別號,若引數為0,則返回當前程序的組識別碼。
定義函式:pid_t getpgid(pid_t pid)
返回值:執行成功則返回正確的組識別碼,若有錯則返-1,錯誤原因存在於errno中。
標頭檔案:#include <unistd.h>

(4)getpgrp()
功能:用來獲得目前程序所屬於的組識別號,等價於getpgid(0)。
定義函式:pid_t getpgrp(void)
返回值:執行成功則返回正確的組識別碼。
標頭檔案:#include <unistd.h>

(5)getpriotity(void)
功能:用來獲得程序,程序組和使用者的程序執行優先權。
定義函式:int getpriority(int which,int who)
引數含義:
which:
PRIO_PROCESS   who為程序的識別碼
PRIO_PGRP     who為程序的組識別碼
PRIO_USER     who為使用者識別碼
返回值:執行成功則返回當前程序的優先順序(-20--20),值越小優先順序越高。若出錯則返-1,原因在errno中。
標頭檔案:#include <sys/resource.h>

簡單例項:

[[email protected] systemCall]$ cat -n get_process_information.c
     1  #include <stdio.h>
     2  #include <unistd.h>
     3  #include <sys/resource.h>
     4
     5  int main(/*int argc,char **argv*/)
     6  {
     7          printf("This process's pid is:%d",getpid());
     8          printf("/nThis process's farther pid is:%d",getppid());
     9          printf("/nThis process's group pid is:%d",getpgid(getpid()));
    10          printf("/nThis process's group pid is:%d",getpgrp());
    11          printf("/nThis process's priority is:%d/n",getpriority(PRIO_PROCESS,getpid()));
    12          return 0;
    13  }
[[email protected] systemCall]$ ./get_process_information
This process's pid is:6172
This process's farther pid is:5681
This process's group pid is:6172
This process's group pid is:6172
This process's priority is:0
[[email protected] systemCall]$  


程序控制函式

程序函式-獲取程序ID

pid_t getpid(void)
功能:獲取本程序ID 
pid_t getppid(void)
功能:獲取父程序ID



程序函式-建立子程序
pid_t fork(void)
功能:建立子程序

fork會被呼叫一次,卻返回兩次,有三種不同的返回值:
1.在父程序中,fork返回子程序建立的PID.
2.在子程序中,fork返回0.
3.如果出現錯誤,fork返回一個負值.
注:子程序會複製程式碼自行執行,子程序中的變數不影響父程序,子程序執行的次序不確定.

pid_t vfork(void)
功能:建立子程序
vfork會被呼叫一次,卻返回兩次,有三種不同的返回值:
1.在父程序中,vfork返回子程序建立的PID.
2.在子程序中,vfork返回0.
3.如果出現錯誤,vfork返回一個負值.
注:子程序與父程序共享資料段,子程序中的變數與父程序保持一致,子程序比父程序優先執行.



程序函式-exec函式
注:exec函式啟動一個新的程式,會替換原有的程序,因此程序的PID保持不變.
int execl(const char * path , const char * arg1 , ...)
變數 作用
path 被執行程式名(含完整路徑)
arg1 - argn 被執行程式所需的命令列引數,含程式名.以空指標(NULL)結束.

int execlp(const char * path , const char * arg1 , ...)
變數 作用
path 被執行的程式名(不含路徑,將從PATH環境變數中查詢該程式)
arg1 - argn 被執行程式所需的命令列引數,含程式名.以空指標(NULL)結束.

int execv(const char * path , char * const argv[])
變數 作用
path 被執行程式名(含完整路徑)
argv[ ] 被執行程式所需要的命令列引數陣列.

int system(const char* string)
功能:呼叫fork產生子程序,由子程序呼叫"/bin/sh -c string"來執行引數string所代表的命令與引數.



程序函式-程序等待
pid_t wait(int * status)
功能:阻塞該程序,直到其某個子程序退出.

int pause(void)
功能:pause只有在執行了一個訊號處理程式並從其返回時,pause才返回. 守護程序 五步走+出錯處理 1,建立子程序,父程序退出 2,setsid() 3,切換目錄 4,umask 5,釋放檔案資源 出錯處理syslog   openlog closelog

第三部份:程序程式設計例項

多程序例項

/* multi_proc.c */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
	pid_t child1, child2, child;
	
	/*ŽŽœšÁœžö×Óœø³Ì*/
	child1 = fork();
		
	/*×Óœø³Ì1µÄ³öŽíŽŠÀí*/
	if (child1 == -1)
	{
		printf("Child1 fork error\n");
		exit(1);
	}
	else if (child1 == 0) /*ÔÚ×Óœø³Ì1Öе÷ÓÃexeclpº¯Êý*/
	{
		printf("In child1: execute 'ls -l'\n");
		
		if (execlp("ls", "ls", "-l", NULL) < 0)
		{
			printf("Child1 execlp error\n");
		}
  	}
  	else /*ÔÚžžœø³ÌÖеȎý×Óœø³Ì2µÄÍ˳ö*/
  	{
  		child2 = fork();
  		if (child2 == -1) /*×Óœø³Ì2µÄ³öŽíŽŠÀí*/
  		{
  			printf("Child2 fork error\n");
  			exit(1);
  		}
  		else if( child2 == 0 ) /*ÔÚ×Óœø³Ì2ÖÐʹÆäÔÝÍ£5s*/
  		{
  			printf("In child2: sleep for 5 seconds and then exit\n");
  			sleep(5);
  			exit(0);
  		}
  		
  		printf("In father process:\n");
  		
  		child = waitpid(child1, NULL, 0);
  		if (child == child1)
  		{
  			printf("Get child1 exit code\n");
  		}
  		else
  		{
  			printf("Error occured!\n");
  		}
  		
  		do
  		{
  			child = waitpid(child2, NULL, WNOHANG );
  			
  			if (child == 0)
  			{
  				printf("The child2 process has not exited!\n");
  				sleep(1);
  			}
  		} while (child == 0);
  		
  		if (child == child2)
  		{
  			printf("Get child2 exit code\n");
  		}
  		else
  		{
  			printf("Error occured!\n");
  		}
  	}
  	
  	exit(0);
}


守護程序例項

/* daemon_proc.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <syslog.h>

int main(void)
{
	pid_t child1,child2;
	int i;
	
	/*建立子程序1*/
	child1 = fork();
		
	if (child1 ==  1)
	{
		perror("child1 fork");
		exit(1);
	}
	else if (child1 > 0)
	{
		exit(0);
	}
	
	/*開啟日誌服務*/
	openlog("daemon_proc_info", LOG_PID, LOG_DAEMON);
	
	/*以下幾步是編寫守護程序的常規步驟*/
	setsid();
	chdir("/");
	umask(0);
	for(i = 0; i < getdtablesize(); i++)
	{
		close(i);
	}
	
	/*建立子程序2*/
	child2 = fork();
	if (child2 ==  1)
	{
		perror("child2 fork");
		exit(1);
	}
	else if (child2 == 0)
	{
		/*在日誌中寫入字串*/
		syslog(LOG_INFO, " child2 will sleep for 10s ");
		sleep(10);
		syslog(LOG_INFO, " child2 is going to exit! ");
		exit(0);
	}
	else
	{
		waitpid(child2, NULL, 0);
		syslog(LOG_INFO, " child1 noticed that child2 has exited ");
		
		/*關閉日誌服務*/
  		closelog();
  		while(1)
  		{
  			sleep(10);
  		}	
  	}
}



相關推薦

Linux-C成長之路Linux C程式設計實戰之路 複合資料型別

Linux C程式設計實戰之路 複合資料型別 咱們知道,C語言中有許多基本資料型別,比如int型,float型,double型等,我們經常使用這些基本資料型別來表達一些簡單的資料,比如一個人的年齡可以用 int 型資料來表示,一本書的價格可以用 float 型

C語言程序設計基礎最後一次作業-- 總結報告

人際關系 領域 健康 作用 每次 收獲 會有 做出 理解 一、總體總結 1、當初你是如何做出選擇計算機專業的決定的?經過一個學期,你的看法改變了麽,為什麽? 你覺得計算機是你喜歡的領域嗎,它是你擅長的領域嗎? 為什麽? 當初填報誌願時,是我自己選擇的計算機專業,同時也采取

C++ vector的用法整理

vector 是向量型別,它可以容納許多型別的資料,如若干個整數,所以稱其為容器。vector 是C++ STL的一個重要成員,使用它時需要包含標頭檔案: #include<vector>; 一、vector 的初始化:可以有五種方式,舉例說明如下: (1) vector&

Linux應用快捷鍵彙集整理

原文地址:http://blog.chinaunix.net/uid-21123336-id-1830510.html Gnome快捷鍵 通用快捷鍵 Alt + F1 類似Windows下的Win鍵,在GNOME中開啟"應用程式"選單(Applications) Alt +

Linux學習之程序通訊

言之者無罪,聞之者足以戒。 ——《詩序》 ctrl+alt+t     開啟終端 一、程序間通訊和執行緒間通訊: 程序通訊:在使用者空間實現程序通訊是不可能的,通過Linux核心通訊 執行緒通訊:可以在使用者空間就可以實現,可以通過全域性變數通訊 二、通訊方式:

Linux學習之程序通訊

言之者無罪,聞之者足以戒。 ——《詩序》 命令:kill -l   可以檢視核心可以傳送多少種訊號 命令:ps -axj 可以檢視程序的狀態 訊號: 訊號通訊,其實就是核心向用戶空間程序傳送訊號,只有核心才能發訊號,使用者空間程序不能傳送訊號 訊號通訊的框架: (

Linux學習之程序通訊

言之者無罪,聞之者足以戒。 ——《詩序》 二、訊號的接收 接收訊號的程序,需要的條件:要想使接收的程序能收到訊號,這個程序就不能結束 接收訊號的函式:sleep()、while(1)、pause() sleep()函式使程序進入睡眠狀態(S) pause()函式使程

Linux學習之程序通訊

言之者無罪,聞之者足以戒。 ——《詩序》 IPC通訊 IPC通訊有三種:共享記憶體、訊息佇列、訊號燈 這個IPC物件,是存在於核心中的。而且使用者空間的檔案系統中沒有IPC檔案型別 IPC物件 IPC和檔案IO函式的比較: 檔案I/O

Linux學習之程序通訊

言之者無罪,聞之者足以戒。 ——《詩序》 訊息佇列: 鏈式佇列: msqid ds  維護訊息佇列的結構體,佇列的第一個訊息指標msg_first,最後一個訊息指標msg_last 訊息中有一個成員指標next 每一個訊息中包含有哪些內容: Data    

linux c用open開啟建立一個檔案

1、檔案描述符 Linux作業系統核心(kernel)利用檔案描述符來訪問檔案,檔案描述符大於等於0,是一個使用者描述被開啟檔案的索引值,它指向該檔案的相關資訊記錄表,當檔案開啟或者建立新檔案的時,就會返回一個檔案描述符,當讀寫檔案時,也需要使用檔案描述符來指定特寫檔案。

Linux--C語言操作資料庫插入資料

 各種渠道去找有關於使用C語言操作資料庫的資料,好辛苦,弄出來了! 資料庫部分 首先建立一張表 create table children(childno int not null unique,fname varchar(20),age int);

linux 編寫守護程序例子 Daemon

例子如下 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h>  //fork int Daemon(void)

C++ set用法總結整理

順序容器包括vector、deque、list、forward_list、array、string,所有順序容器都提供了快速順序訪問元素的能力。 關聯容器包括set、map 關聯容器和順序容器有著根本的不同:關聯容器中的元素是按關鍵字來儲存和訪問的。與之相對,順序容器

Linux 筆試面試常見題目整理

一.填空題: 在Linux系統中,以 檔案 方式訪問裝置 。 Linux核心引導時,從檔案 /etc/fstab 中讀取要載入的檔案系統。 Linux檔案系統中每個檔案用 i節點 來標識。 全部磁碟塊由四個部分組成,分別為引導塊 、專用塊 、 i節點表塊 和

linux c程式設計 程序程式設計整理

(程式碼來自《嵌入式linux應用程式開發標準教程》) 概覽: 第一部份:程序簡介 第二部份:程序控制  :命令  函式 第三部份:程序例項:  多程序  守護程序 第四部份:附加材料 linux 程序控制函式大全     第一部份:程序簡介 程序是Lin

Linux C 之檔案程式設計2

read & write #read 從與檔案描述符 fd 相關的檔案中讀取 n bytes 個位元組的資料到 buf 中,返回實際讀入的位元組數; ##write 將字串 buf 中前 n bytes 個位元組的資料寫入與檔案描述符 fd 關聯的檔案中,

Linux C高階程式設計——網路程式設計之UDP4

Linux網路程式設計——UDP 宗旨:技術的學習是有限的,分享的精神是無限的。 下面分析一幀基於UDP的TFTP協議幀。 乙太網首部 0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00 IP首部0000: 45 00 00

Linux C高階程式設計——網路程式設計之乙太網2

Linux網路程式設計——乙太網 宗旨:技術的學習是有限的,分享的精神是無限的。 1、乙太網幀格式         源地址和目的地址是指網絡卡的硬體地址(也叫MAC地址),長度是48位,是在網絡卡出廠時固化的。用ifconfig命令檢視,“ 硬體地址 00:0c:29

Linux C高階程式設計——網路程式設計之API5

Linux C網路程式設計——API 宗旨:技術的學習是有限的,分享的精神的無限的。 一、基本socket函式         Linux系統是通過提供套接字(socket)來進行網路程式設計的。網路的socket資料傳輸是一種特殊的I/O,socket也是一種檔案描述

Linux C高階程式設計——網路程式設計之TCP3

Linux網路程式設計(三)——TCP 宗旨:技術的學習是有限的,分享的精神是無限的。 1、TCP段格式         和UDP協議一樣也有源埠號和目的埠號,通訊的雙方由IP地址和埠號標識。32位序號、32位確認序號、視窗大小。4位首部長度和IP協議頭類似,表示TCP協議頭的長度,以4位元組為單位,