當前位置:首頁 » 操作系統 » linuxc程序設計pdf

linuxc程序設計pdf

發布時間: 2023-08-07 06:57:12

A. linux操作系統上c語言編程入門怎麼解決

Linux程序設計入門--進程介紹
Linux下進程的創建
前言:
這篇文章是用來介紹在Linux下和進程相關的各個概念.我們將會學到:
進程的概念
進程的身份
進程的創建
守護進程的創建
----------------------------------------
----
1。進程的概念
Linux操作系統是面向多用戶的.在同一時間可以有許多用戶向操作系統發出各種命
令.那麼操作系統是怎麼實現多用戶的環境呢? 在現代的操作系統裡面,都有程序和進程
的概念.那麼什麼是程序,什麼是進程呢? 通俗的講程序是一個包含可以執行代碼的文件
,是一個靜態的文件.而進程是一個開始執行但是還沒有結束的程序的實例.就是可執行文
件的具體實現. 一個程序可能有許多進程,而每一個進程又可以有許多子進程.依次循環
下去,而產生子孫進程. 當程序被系統調用到內存以後,系統會給程序分配一定的資源(內
存,設備等等)然後進行一系列的復雜操作,使程序變成進程以供系統調用.在系統裡面只
有進程沒有程序,為了區分各個不同的進程,系統給每一個進程分配了一個ID(就象我們的
身份證)以便識別. 為了充分的利用資源,系統還對進程區分了不同的狀態.將進程分為新
建,運行,阻塞,就緒和完成五個狀態. 新建表示進程正在被創建,運行是進程正在運行,阻
塞是進程正在等待某一個事件發生,就緒是表示系統正在等待CPU來執行命令,而完成表示
進程已經結束了系統正在回收資源. 關於進程五個狀態的詳細解說我們可以看《操作系
統》上面有詳細的解說。
2。進程的標志
上面我們知道了進程都有一個ID,那麼我們怎麼得到進程的ID呢?系統調用getpid可
以得到進程的ID,而getppid可以得到父進程(創建調用該函數進程的進程)的ID.
#include <unistd>
pid_t getpid(void);
pid_t getppid(void);
進程是為程序服務的,而程序是為了用戶服務的.系統為了找到進程的用戶名,還為進程和
用戶建立聯系.這個用戶稱為進程的所有者.相應的每一個用戶也有一個用戶ID.通過系統
調用getuid可以得到進程的所有者的ID.由於進程要用到一些資源,而Linux對系統資源是
進行保護的,為了獲取一定資源進程還有一個有效用戶ID.這個ID和系統的資源使用有關
,涉及到進程的許可權. 通過系統調用geteuid我們可以得到進程的有效用戶ID. 和用戶ID
相對應進程還有一個組ID和有效組ID系統調用getgid和getegid可以分別得到組ID和有效
組ID
#include <unistd>
#include <sys/types.h>

uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
git_t getegid(void);
有時候我們還會對用戶的其他信息感興趣(登錄名等等),這個時候我們可以調用getpwui
d來得到.
struct passwd {
char *pw_name; /* 登錄名稱 */
char *pw_passwd; /* 登錄口令 */
uid_t pw_uid; /* 用戶ID */
gid_t pw_gid; /* 用戶組ID */
char *pw_gecos; /* 用戶的真名 */
char *pw_dir; /* 用戶的目錄 */
char *pw_shell; /* 用戶的SHELL */
};
#include <pwd.h>
#include <sys/types.h>

struct passwd *getpwuid(uid_t uid);
下面我們學習一個實例來實踐一下上面我們所學習的幾個函數:
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc,char **argv)
{
pid_t my_pid,parent_pid;
uid_t my_uid,my_euid;
gid_t my_gid,my_egid;
struct passwd *my_info;
my_pid=getpid();
parent_pid=getppid();
my_uid=getuid();
my_euid=geteuid();
my_gid=getgid();
my_egid=getegid();
my_info=getpwuid(my_uid);
printf("Process ID:%ld/n",my_pid);
printf("Parent ID:%ld/n",parent_pid);
printf("User ID:%ld/n",my_uid);
printf("Effective User ID:%ld/n",my_euid);
printf("Group ID:%ld/n",my_gid);
printf("Effective Group ID:%ld/n",my_egid):
if(my_info)
{
printf("My Login Name:%s/n" ,my_info->pw_name);
printf("My Password :%s/n" ,my_info->pw_passwd);
printf("My User ID :%ld/n",my_info->pw_uid);
printf("My Group ID :%ld/n",my_info->pw_gid);
printf("My Real Name:%s/n" ,my_info->pw_gecos);
printf("My Home Dir :%s/n", my_info->pw_dir);
printf("My Work Shell:%s/n", my_info->pw_shell);
}
}
3。進程的創建
創建一個進程的系統調用很簡單.我們只要調用fork函數就可以了.
#include <unistd.h>

pid_t fork();
當一個進程調用了fork以後,系統會創建一個子進程.這個子進程和父進程不同的地方只
有他的進程ID和父進程ID,其他的都是一樣.就象符進程克隆(clone)自己一樣.當然創建
兩個一模一樣的進程是沒有意義的.為了區分父進程和子進程,我們必須跟蹤fork的返回
值. 當fork掉用失敗的時候(內存不足或者是用戶的最大進程數已到)fork返回-1,否則f
ork的返回值有重要的作用.對於父進程fork返回子進程的ID,而對於fork子進程返回0.我
們就是根據這個返回值來區分父子進程的. 父進程為什麼要創建子進程呢?前面我們已經
說過了Linux是一個多用戶操作系統,在同一時間會有許多的用戶在爭奪系統的資源.有時
進程為了早一點完成任務就創建子進程來爭奪資源. 一旦子進程被創建,父子進程一起從
fork處繼續執行,相互競爭系統的資源.有時候我們希望子進程繼續執行,而父進程阻塞直
到子進程完成任務.這個時候我們可以調用wait或者waitpid系統調用.
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);
wait系統調用會使父進程阻塞直到一個子進程結束或者是父進程接受到了一個信號.如果
沒有父進程沒有子進程或者他的子進程已經結束了wait回立即返回.成功時(因一個子進
程結束)wait將返回子進程的ID,否則返回-1,並設置全局變數errno.stat_loc是子進程的
退出狀態.子進程調用exit,_exit 或者是return來設置這個值. 為了得到這個值Linux定
義了幾個宏來測試這個返回值.
WIFEXITED:判斷子進程退出值是非0
WEXITSTATUS:判斷子進程的退出值(當子進程退出時非0).
WIFSIGNALED:子進程由於有沒有獲得的信號而退出.
WTERMSIG:子進程沒有獲得的信號號(在WIFSIGNALED為真時才有意義).
waitpid等待指定的子進程直到子進程返回.如果pid為正值則等待指定的進程(pid).如果
為0則等待任何一個組ID和調用者的組ID相同的進程.為-1時等同於wait調用.小於-1時等
待任何一個組ID等於pid絕對值的進程. stat_loc和wait的意義一樣. options可以決定
父進程的狀態.可以取兩個值 WNOHANG:父進程立即返回當沒有子進程存在時. WUNTACHE
D:當子進程結束時waitpid返回,但是子進程的退出狀態不可得到.
父進程創建子進程後,子進程一般要執行不同的程序.為了調用系統程序,我們可以使用系
統調用exec族調用.exec族調用有著5個函數.
#include <unistd.h>
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv[]):
exec族調用可以執行給定程序.關於exec族調用的詳細解說可以參考系統手冊(man exec
l). 下面我們來學習一個實例.注意編譯的時候要加 -lm以便連接數學函數庫.
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>
void main(void)
{
pid_t child;
int status;
printf("This will demostrate how to get child status/n");
if((child=fork())==-1)
{
printf("Fork Error :%s/n",strerror(errno));
exit(1);
}
else if(child==0)
{
int i;
printf("I am the child:%ld/n",getpid());
for(i=0;i<1000000;i++) sin(i);
i=5;
printf("I exit with %d/n",i);
exit(i);
}
while(((child=wait(&status))==-1)&(errno==EINTR));
if(child==-1)
printf("Wait Error:%s/n",strerror(errno));
else if(!status)
printf("Child %ld terminated normally return status is zero/n",
child);
else if(WIFEXITED(status))
printf("Child %ld terminated normally return status is %d/n",
child,WEXITSTATUS(status));
else if(WIFSIGNALED(status))
printf("Child %ld terminated e to signal %d znot caught/n",
child,WTERMSIG(status));
}
strerror函數會返回一個指定的錯誤號的錯誤信息的字元串.
4。守護進程的創建
如果你在DOS時代編寫過程序,那麼你也許知道在DOS下為了編寫一個常駐內存的程序
我們要編寫多少代碼了.相反如果在Linux下編寫一個"常駐內存"的程序卻是很容易的.我
們只要幾行代碼就可以做到. 實際上由於Linux是多任務操作系統,我們就是不編寫代碼
也可以把一個程序放到後台去執行的.我們只要在命令後面加上&符號SHELL就會把我們的
程序放到後台去運行的. 這里我們"開發"一個後台檢查郵件的程序.這個程序每個一個指
定的時間回去檢查我們的郵箱,如果發現我們有郵件了,會不斷的報警(通過機箱上的小喇
叭來發出聲音). 後面有這個函數的加強版本加強版本
後台進程的創建思想: 首先父進程創建一個子進程.然後子進程殺死父進程(是不是很無
情?). 信號處理所有的工作由子進程來處理.
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
/* Linux 的默任個人的郵箱地址是 /var/spool/mail/用戶的登錄名 */
#define MAIL "/var/spool/mail/hoyt"
/* 睡眠10秒鍾 */

#define SLEEP_TIME 10
main(void)
{
pid_t child;
if((child=fork())==-1)
{
printf("Fork Error:%s/n",strerror(errno));
exit(1);
}
else if(child>0)
while(1);
if(kill(getppid(),SIGTERM)==-1)
{
printf("Kill Parent Error:%s/n",strerror(errno));
exit(1);
}
{
int mailfd;
while(1)
{
if((mailfd=open(MAIL,O_RDONLY))!=-1)
{
fprintf(stderr,"%s","7");
close(mailfd);
}
sleep(SLEEP_TIME);
}
}
}
你可以在默認的路徑下創建你的郵箱文件,然後測試一下這個程序.當然這個程序還有很
多地方要改善的.我們後面會對這個小程序改善的,再看我的改善之前你可以嘗試自己改
善一下.比如讓用戶指定郵相的路徑和睡眠時間等等.相信自己可以做到的.動手吧,勇敢
的探險者.
好了進程一節的內容我們就先學到這里了.進程是一個非常重要的概念,許多的程序都會
用子進程.創建一個子進程是每一個程序員的基本要求!

B. 求《LINUXC編程一站式學習》全文免費下載百度網盤資源,謝謝~

《LINUX C編程一站式學習》網路網盤pdf最新全集下載:
鏈接:https://pan..com/s/1wIgN0sfCc9gjkgPdARtUng

?pwd=4jut 提取碼:4jut
簡介:通俗易懂的原理剖析,有非常適合初學者的code,有形象化的展示。本書分為兩部分:第一部分講解編程語言和程序設計的基本思想方法,讓讀者從概念上認識C語言。

C. 在Linux系統中,如何運行一個C語言程序

1、打開kali linux的終端。創建一個文件並命名為test.c。在終端輸入:touch test.c。

D. linux C語言編程,socket實現的即使通訊系統

Socket通信創建步驟:

(1)通過socket()函數創建socket
(2)通過bind函數綁定socket於設備地址
(3)進行讀寫操作read/recv/recvfrom write/send/sendto
(4)close方法關閉套接字


例子如下:

test1.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>

intmain(void)
{
//createsocket
intfd=socket(AF_INET,SOCK_DGRAM,0);
if(fd==-1)
{
perror("socket ");
exit(-1);
}
printf("socketfd=%d ",fd);

//buildconnectionaddress
structsockaddr_inaddr;
addr.sin_family=AF_INET;
addr.sin_port=htons(6666);
addr.sin_addr.s_addr=inet_addr("127.0.0.1");

intr;
r=bind(fd,(structsockaddr*)&addr,sizeof(addr));
if(r==-1)
{
perror("bind");
close(fd);
exit(-1);
}
printf("bindaddresssuccessful! ");
//acceptorsendmessage
charbuf[255];
structsockaddr_infrom;
socklen_tlen;
len=sizeof(from);
while(1)
{
r=recvfrom(fd,buf,sizeof(buf)-1,0,(structsockaddr*)&from,&len);
if(r>0)
{
buf[r]=0;
printf("Themessagefrom%sis:%s ",inet_ntoa(from.sin_addr),buf);
}
else
{
break;
}
}
//closesocket
close(fd);
return0;
}

test2.c

java">#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

intmain(void)
{
//createsocket
intfd=socket(AF_INET,SOCK_DGRAM,0);
if(fd==-1)
{
perror("socket");
exit(-1);
}
printf("createsocketOK! ");
//createansendaddress
structsockaddr_inaddr={};
addr.sin_family=AF_INET;
addr.sin_port=htons(6666);
addr.sin_addr.s_addr=inet_addr("127.0.0.1");
//
intr;
charbuf[255];
while(1)
{
r=read(0,buf,sizeof(buf)-1);
if(r<=0)
break;
sendto(fd,buf,r,0,(structsockaddr*)&addr,sizeof(addr));
}
//closesocket
close(fd);
return0;
}

先運行test1.c,然後運行test2.c,在test2.c運行後輸入內容,在test1.c所在終端中就會顯示信息

運行結果如下:

E. 《自製編譯器》pdf下載在線閱讀,求百度網盤雲資源

《自製編譯器》[日]青木峰郎電子書網盤下載免費在線閱讀

鏈接:

密碼:ufdr

書名:自製編譯器
作者名:[日]青木峰郎
豆瓣評分:7.7
出版社:人民郵電出版社
出版年份:2016-6
頁數:472
內容介紹:
本書將帶領讀者從頭開始製作一門語言的編譯器。筆者特意為本書設計了CЬ語言,CЬ可以說是C語言的子集,實現了包括指針運算等在內的C語言的主要部分。本書所實現的編譯器就是C Ь語言的編譯器, 是實實在在的編譯器,而非有諸多限制的玩具。另外,除編譯器之外,本書對以編譯器為中心的編程語言的運行環境,即編譯器、匯編器、鏈接器、硬體、運行時環境等都有所提及,介紹了程序運行的所有環節。
作者介紹:
程序員,著有《Ruby程序設計268技(第2版)》《Ruby源代碼完全解說》《Linux程序設計》等多部編程相關著作。並積極參與標准庫維護、文檔維護等各種各樣的活動。

F. linux程序設計:堆和棧的區別

一、預備知識—程序的內存分配
一個由C/C++編譯的程序佔用的內存分為以下幾個部分
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變數的值等。其
操作方式類似於數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回
收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3、全局區(靜態區)(static)—,全局變數和靜態變數的存儲是放在一塊的,初始化的
全局變數和靜態變數在一塊區域, 未初始化的全局變數和未初始化的靜態變數在相鄰的另
一塊區域。 - 程序結束後由系統釋放。
4、文字常量區 —常量字元串就是放在這里的。 程序結束後由系統釋放
5、程序代碼區—存放函數體的二進制代碼。

二、例子程序
這是一個前輩寫的,非常詳細
//main.cpp
int a = 0; 全局初始化區
char *p1; 全局未初始化區
main()
{
int b; 棧
char s[] = "abc"; 棧
char *p2; 棧
char *p3 = "123456"; 123456/0在常量區,p3在棧上。
static int c =0; 全局(靜態)初始化區
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得來得10和20位元組的區域就在堆區。
strcpy(p1, "123456"); 123456/0放在常量區,編譯器可能會將它與p3所指向的"123456"
優化成一個地方。
}

二、堆和棧的理論知識
2.1申請方式
stack:
由系統自動分配。 例如,聲明在函數中一個局部變數 int b; 系統自動在棧中為b開辟空

heap:
需要程序員自己申請,並指明大小,在c中malloc函數
如p1 = (char *)malloc(10);
在C++中用new運算符
如p2 = new char[10];
但是注意p1、p2本身是在棧中的。

2.2
申請後系統的響應
棧:只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常提示棧溢
出。
堆:首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,
會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑結點鏈表
中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的
首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。
另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部
分重新放入空閑鏈表中。

2.3申請大小的限制
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意
思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(也有
的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將
提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲
的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小
受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。

2.4申請效率的比較:
棧由系統自動分配,速度較快。但程序員是無法控制的。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,他不是在堆,也不是在棧是
直接在進程的地址空間中保留一塊內存,雖然用起來最不方便。但是速度快,也最靈活。

2.5堆和棧中的存儲內容
棧: 在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可
執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧
的,然後是函數中的局部變數。注意靜態變數是不入棧的。
當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向最開始存的地
址,也就是主函數中的下一條指令,程序由該點繼續運行。
堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容由程序員安排。

2.6存取效率的比較

char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在運行時刻賦值的;
而bbbbbbbbbbb是在編譯時就確定的;
但是,在以後的存取中,在棧上的數組比指針所指向的字元串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
對應的匯編代碼
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一種在讀取時直接就把字元串中的元素讀到寄存器cl中,而第二種則要先把指針值讀到
edx中,再根據edx讀取字元,顯然慢了。

2.7小結:
堆和棧的區別可以用如下的比喻來看出:
使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就 走,不必理會切菜、洗菜等准備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自 由度小。
使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由

G. 《Linux環境編程:從應用到內核》pdf下載在線閱讀全文,求百度網盤雲資源

《Linux環境編程:從應用到內核》網路網盤pdf最新全集下載:
鏈接:https://pan..com/s/1IPqpwxE_ZBlsWO0F6NW82g

?pwd=07dh 提取碼:07dh
簡介:《LUNIX環境高級編程》(簡稱APUE)幾乎是Linux領域程序員人手必備的一本書,但在掌握和理解APU[的內容後,又該如何繼續提高自己的技能,如何更深入地理解Linux環境編程及其背後的工作機制呢?本書將從一個全新的角度帶領讀者重新進入Linux環境編程,從應用出發,深入內核源碼,研究Linux各介面的工作機制和原理,讓讀者不僅知其然,還知其所以然。作為Linux開發工程師,如果不僅掌握Linux的應用層開發,同時還熟悉Linux的內核源碼,那麼在Linux環境下設計開發任何產品都將游刀有餘,穩定且高效。

本書是Linux技術專家高峰和李彬的合力之作,是兩個人多年開發經驗的總結和分享,也是市場上**一本將Linux應用態與內核態相結合的技術圖書,選擇這種寫作方式是為了向APUE的作者致敬。本書涵蓋了APUE中大部分章節的內容,並針對Linux環境,根據作者多年經驗,詳細解析了Linux常用介面的使用方法和陷阱。為了讓讀者更清楚地理解介面的工作原理,對於絕大部分介面,作者都深入仁庫或內核源碼進行全面分析。希望本書可以幫助讀者打通Linux環境的應用和內核兩條脈絡,使兩條線融會貫通,進一步提高開發水平。

熱點內容
qq啟動腳本 發布:2025-03-12 19:59:00 瀏覽:893
電腦配置有ssd是什麼意思 發布:2025-03-12 19:57:50 瀏覽:730
米思齊編譯失敗怎麼看 發布:2025-03-12 19:26:27 瀏覽:848
sql語句notexists 發布:2025-03-12 19:16:11 瀏覽:60
快手安卓版如何玩 發布:2025-03-12 19:15:26 瀏覽:36
scott資料庫 發布:2025-03-12 19:15:19 瀏覽:873
rom伺服器是什麼 發布:2025-03-12 19:10:27 瀏覽:62
我給你改個密碼叫什麼 發布:2025-03-12 19:09:32 瀏覽:674
寬頻密碼在手機上如何更改 發布:2025-03-12 19:07:52 瀏覽:116
python離線安裝pip 發布:2025-03-12 19:06:18 瀏覽:29