日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux c 开发

發(fā)布時(shí)間:2023/12/31 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux c 开发 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在很多人的眼里,C語言和linux常常是分不開的。這其中的原因很多,其中最重要的一部分我認(rèn)為是linux本身就是C語言的杰出作品。當(dāng)然,linux操作系統(tǒng)本身對C語言的支持也是相當(dāng)?shù)轿坏摹W鳛橐粋€(gè)真正的程序員來說,如果沒有在linux下面用C語言編寫過完整的程序,那么只能說他對C語言本身的理解還相關(guān)膚淺,對系統(tǒng)本身的認(rèn)識(shí)也不夠到位。作為程序員來說,linux系統(tǒng)為我們提供了很多理想的環(huán)境,這其中包括了下面幾個(gè)方面,

(1)完善的編譯環(huán)境,包括gcc、as、ld等編譯、鏈接工具 (2)強(qiáng)大的調(diào)試環(huán)境,主要是gdb工具 (3)豐富的自動(dòng)編譯工具,主要是make工具 (4)多樣化的os選擇,ubuntu、redflag等等 (5)浩瀚的開源代碼庫

當(dāng)然,不管我怎么說,最終朋友們還是應(yīng)該自己勇敢地跨出前進(jìn)的第一步。 如果還沒有過Linux編程經(jīng)驗(yàn)的朋友可以首先在自己的pc上面安裝一個(gè)虛擬機(jī),然后就可以在shell下面編寫自己的C語言代碼了。

#include <stdio.h> int main() {printf("hello!\n");return 1; }

編寫完上面的代碼后,你需要做的就是兩個(gè)步驟: 1、輸入 gcc hello.c -o hello; 2、輸入./hello。 如果一切正常的話,此時(shí)你應(yīng)該會(huì)在屏幕上看到一行hello的打印。如果你看到了,那么恭喜你,你已經(jīng)可以開始linux的c語言編程之旅了。

當(dāng)然,我們不會(huì)滿足于這么簡單的打印功能。下面就可以編寫一個(gè)簡單的迭代函數(shù),

#include <stdio.h> int iterate(int value) {if(1 == value)return 1;return iterate(value - 1) + value; } int main() {printf("%d\n", iterate(10));return 1; }

此時(shí),同樣我們需要重復(fù)上面的步驟: 1、輸入gcc hello.c -o hello; 2、輸入./hello。 當(dāng)然此時(shí)如果一切OK的話,你就會(huì)看到屏幕會(huì)有55這個(gè)數(shù)的輸出。本來1到10的數(shù)據(jù)之和就是55, 這說明我們的程序是正確的。

當(dāng)然, 還會(huì)有一些朋友對程序的反匯編感興趣,那么他需要兩個(gè)步驟: 1、gcc hello.c -g -o hello; 2、objdump -S -d ./hello。 之所以在gcc編譯的時(shí)候加上-g是為了添加調(diào)試信息,objdump中的-S選項(xiàng)是為了在顯示匯編代碼的時(shí)候同時(shí)顯示原來的C語言源代碼。

int iterate(int value) {8048374: 55 push %ebp8048375: 89 e5 mov %esp,%ebp8048377: 83 ec 08 sub $0x8,%espif(1 == value)804837a: 83 7d 08 01 cmpl $0x1,0x8(%ebp)804837e: 75 09 jne 8048389 <iterate+0x15>return 1;8048380: c7 45 fc 01 00 00 00 movl $0x1,0xfffffffc(%ebp)8048387: eb 16 jmp 804839f <iterate+0x2b>return iterate(value -1) + value;8048389: 8b 45 08 mov 0x8(%ebp),%eax804838c: 83 e8 01 sub $0x1,%eax804838f: 89 04 24 mov %eax,(%esp)8048392: e8 dd ff ff ff call 8048374 <iterate>8048397: 8b 55 08 mov 0x8(%ebp),%edx804839a: 01 c2 add %eax,%edx804839c: 89 55 fc mov %edx,0xfffffffc(%ebp)804839f: 8b 45 fc mov 0xfffffffc(%ebp),%eax } 80483a2: c9 leave 80483a3: c3 ret

linux下的C語言開發(fā)(makefile編寫) 對于程序設(shè)計(jì)員來說,makefile是我們繞不過去的一個(gè)坎。可能對于習(xí)慣Visual C++的用戶來說,是否會(huì)編寫makefile無所謂。畢竟工具本身已經(jīng)幫我們做好了全部的編譯流程。但是在Linux上面,一切變得不一樣了,沒有人會(huì)為你做這一切。編代碼要靠你,測試要靠你,最后自動(dòng)化編譯設(shè)計(jì)也要靠你自己。想想看,如果你下載了一個(gè)開源軟件,卻因?yàn)樽詣?dòng)化編譯失敗,那將會(huì)在很大程度上打擊你學(xué)習(xí)代碼的自信心了。所以,我的理解是這樣的。我們要學(xué)會(huì)編寫makefile,至少會(huì)編寫最簡單的makefile。

首先編寫add.c文件,

#include "test.h" #include <stdio.h> int add(int a, int b) {return a + b; } int main() {printf(" 2 + 3 = %d\n", add(2, 3));printf(" 2 - 3 = %d\n", sub(2, 3));return 1; }

再編寫sub.c文件,

#include "test.h" int sub(int a, int b) {return a - b; }

最后編寫test.h文件,

#ifndef _TEST_H #define _TEST_H int add(int a, int b); int sub(int a, int b); #endif

那么,就是這三個(gè)簡單的文件,應(yīng)該怎么編寫makefile呢?

test: add.o sub.o gcc -o test add.o sub.o add.o: add.c test.h gcc -c add.c sub.o: sub.c test.h gcc -c sub.c clean: rm -rf test rm -rf *.o

linux下的C語言開發(fā)(gdb調(diào)試) 編寫代碼過程中少不了調(diào)試。在windows下面,我們有visual studio工具。在linux下面呢,實(shí)際上除了gdb工具之外,你沒有別的選擇。那么,怎么用gdb進(jìn)行調(diào)試呢?我們可以一步一步來試試看。

#include <stdio.h> int iterate(int value) {if(1 == value)return 1;return iterate(value - 1) + value; } int main() {printf("%d\n", iterate(10));return 1; }

既然需要調(diào)試,那么生成的可執(zhí)行文件就需要包含調(diào)試的信息,這里應(yīng)該怎么做呢?很簡單,輸入 gcc test.c -g -o test。輸入命令之后,如果沒有編譯和鏈接方面的錯(cuò)誤,你就可以看到 可執(zhí)行文件test了。

調(diào)試的步驟基本如下所示, (01) 首先,輸入gdb test (02) 進(jìn)入到gdb的調(diào)試界面之后,輸入list,即可看到test.c源文件 (03) 設(shè)置斷點(diǎn),輸入 b main (04) 啟動(dòng)test程序,輸入run (05) 程序在main開始的地方設(shè)置了斷點(diǎn),所以程序在printf處斷住 (06) 這時(shí)候,可以單步跟蹤。s單步可以進(jìn)入到函數(shù),而n單步則越過函數(shù) (07) 如果希望從斷點(diǎn)處繼續(xù)運(yùn)行程序,輸入c (08) 希望程序運(yùn)行到函數(shù)結(jié)束,輸入finish (09) 查看斷點(diǎn)信息,輸入 info break (10) 如果希望查看堆棧信息,輸入bt (11) 希望查看內(nèi)存,輸入 x/64xh + 內(nèi)存地址 (12) 刪除斷點(diǎn),則輸入delete break + 斷點(diǎn)序號(hào) (13) 希望查看函數(shù)局部變量的數(shù)值,可以輸入print + 變量名 (14)希望修改內(nèi)存值,直接輸入 print + *地址 = 數(shù)值 (15) 希望實(shí)時(shí)打印變量的數(shù)值,可以輸入display + 變量名 (16) 查看函數(shù)的匯編代碼,輸入 disassemble + 函數(shù)名 (17) 退出調(diào)試輸入quit即可

linux下的C語言開發(fā)(AT&T 匯編語言) 同樣是x86的cpu,但是卻可以用不同形式的匯編語言來表示。 在window上面我們使用的更多是intel格式的匯編語言,而在Linux系統(tǒng)上面使用的更多的常常是AT&T格式的匯編語言。那什么是AT&T格式的匯編代碼呢?我們可以寫一個(gè)試試看。

.data message: .string "hello!\n" length = . - message .text .global _start _start: movl $length, %edx movl $message, %ecx movl $1, %ebx movl $4, %eax int $0x80 movl $0, %ebx movl $1, %eax int $0x80 08048074 <_start>: .text .global _start _start: movl $length, %edx 8048074: ba 08 00 00 00 mov $0x8,%edx movl $message, %ecx 8048079: b9 9c 90 04 08 mov $0x804909c,%ecx movl $1, %ebx 804807e: bb 01 00 00 00 mov $0x1,%ebx movl $4, %eax 8048083: b8 04 00 00 00 mov $0x4,%eax int $0x80 8048088: cd 80 int $0x80 movl $0, %ebx 804808a: bb 00 00 00 00 mov $0x0,%ebx movl $1, %eax 804808f: b8 01 00 00 00 mov $0x1,%eax int $0x80 8048094: cd 80 int $0x80 ret 8048096: c3 ret

這是一個(gè)簡單的匯編文件,我們可以分兩步進(jìn)行編譯。首先,輸入 as -gstabs -o hello.o hello.s, 接著輸入ld -o hello hello.o即可。為了驗(yàn)證執(zhí)行文件是否正確,可以輸入./hello驗(yàn)證一下。 在as命令當(dāng)中,由于我們使用了-gstabs選項(xiàng),因此在hello執(zhí)行文件中是包含調(diào)試信息的。所以,如果想單步調(diào)試的朋友可以輸入gdb hello進(jìn)行調(diào)試。 那么,hello執(zhí)行文件反匯編的代碼又是什么樣的呢?我們可以輸入objdump -S -d hello查看一下。

linux下的C語言開發(fā)(靜態(tài)庫) 在我們編寫軟件的過程當(dāng)中,少不了需要使用別人的庫函數(shù)。因?yàn)榇蠹抑?#xff0c;軟件是一個(gè)協(xié)作的工程。作為個(gè)人來講,你不可能一個(gè)人完成所有的工作。另外,網(wǎng)絡(luò)上一些優(yōu)秀的開源庫已經(jīng)被業(yè)內(nèi)廣泛接受,我們也沒有必要把時(shí)間浪費(fèi)在這些重復(fù)的工作上面。 既然說到了庫函數(shù),那么一般來說庫函數(shù)分為兩種方式:靜態(tài)庫和動(dòng)態(tài)庫。兩者的區(qū)別其實(shí)很小,靜態(tài)庫是必須要鏈接到執(zhí)行文件中去的,而動(dòng)態(tài)庫是不需要鏈接到最后的執(zhí)行文件中的。怎么理解呢?也就是說,對于最后的執(zhí)行文件而言,你是否刪除靜態(tài)庫無所謂。但是,一旦你刪除了動(dòng)態(tài)庫,最后的執(zhí)行文件就玩不轉(zhuǎn)了。 今天我們討論的問題是靜態(tài)庫。為了顯示windows和linux創(chuàng)建靜態(tài)庫之間的差別,我們首先在windows上面利用Visual C++6.0創(chuàng)建一個(gè)靜態(tài)庫。源文件的代碼很簡單,

#include "test.h" int add(int a, int b) {return a + b; }

頭文件代碼也不難,

#ifndef _TEST_H #define _TEST_H int add(int a, int b); #endif

如果你需要在windows上面創(chuàng)建一個(gè)靜態(tài)庫,那么你需要進(jìn)行下面的操作, (1)打開visual C++ 6.0工具,單擊【File】-> 【New】->【Projects】 (2)選擇【W(wǎng)in32 Static Library】,同時(shí)在【Project Name】寫上項(xiàng)目名稱,在【Location】選擇項(xiàng)目保存地址 (3)單擊【Ok】,繼續(xù)單擊【Finish】,再單擊【Ok】,這樣一個(gè)靜態(tài)庫工程就創(chuàng)建好了 (4)重新單擊【File】->【New】->【Files】,選擇【C++ Source Files】, (5)選中【Add to pproject】,將源文件加入到剛才創(chuàng)建的工程中去,在File中輸入文件名+.c后綴 (6)重復(fù)4、5的操作,加入一個(gè)文件名+.h頭文件 (7)分別在頭文件和源文件中輸入上面的代碼,單擊F7按鈕,即可在Debug目錄中生成*.lib靜態(tài)庫文件

那么,在linux下面應(yīng)該怎么運(yùn)行呢?其實(shí)很簡單,兩條命令解決, (1)首先生成*.o文件,輸入gcc -c test.c -o test.o (2)利用ar命令生成靜態(tài)庫,輸入ar rc libtest.a test.o

此時(shí)如果還有一個(gè)hello.c文件使用到了這個(gè)靜態(tài)庫,比如說 ,

#include <stdio.h> #include "test.h" int main() {printf("%d\n", add(2, 3));return 1; }

其實(shí)也很簡單,輸入一個(gè)簡單的命令就可以生成執(zhí)行文件了, (1)首先輸入gcc hello.c -o hello ./libtest.a (2)輸入./hello,驗(yàn)證生成的執(zhí)行文件是否正確 (3)朋友們可以刪除libtest.a文件,重新輸入./hello,驗(yàn)證執(zhí)行文件是否可以正常運(yùn)行

linux下的C語言開發(fā)(動(dòng)態(tài)庫) 動(dòng)態(tài)鏈接庫不是linux獨(dú)有的特性,在windows下面也存在這樣的特性。一般來說,windows下面的動(dòng)態(tài)連接庫是以.dll作為結(jié)尾的,而linux下面的動(dòng)態(tài)連接庫是以.so結(jié)尾的。和靜態(tài)鏈接庫相比,動(dòng)態(tài)連接庫可以共享內(nèi)存資源,這樣可以減少內(nèi)存消耗。另外,動(dòng)態(tài)連接是需要經(jīng)過操作系統(tǒng)加載器的幫助才能被普通執(zhí)行文件發(fā)現(xiàn)的,所以動(dòng)態(tài)連接庫可以減少鏈接的次數(shù)。有了這個(gè)特點(diǎn),我們就不難發(fā)現(xiàn)為什么很多軟件的補(bǔ)丁其實(shí)都是以動(dòng)態(tài)庫發(fā)布的。

那么,在Linux上動(dòng)態(tài)庫是怎么生成的呢?

#include "test.h" int add(int a, int b) {return a + b; }

頭文件格式,

#ifndef _TEST_H #define _TEST_H int add(int a, int b); #endif

此時(shí)如果我們想要生成動(dòng)態(tài)庫,要做的工作其實(shí)非常簡單,輸入gcc -shared -fPIC -o libtest.so test.c即可。回車后輸入ls,我們就可以發(fā)現(xiàn)當(dāng)前目錄下面出現(xiàn)了libtest.so文件。

#include <stdio.h> #include "test.h" int main() {printf("%d\n", add(2, 3));return 1; }

在上面的代碼當(dāng)中,我們發(fā)現(xiàn)使用到了add函數(shù),那么此時(shí)如何才能生成一個(gè)執(zhí)行文件呢?也很簡單,輸入gcc hello.c -o hello ./libtest.so。然后輸入./hello,此時(shí)可以驗(yàn)證一下執(zhí)行文件運(yùn)行是否正確。在編寫靜態(tài)庫的時(shí)候,我說過靜態(tài)庫是匯編鏈接到執(zhí)行文件當(dāng)中的,而動(dòng)態(tài)庫不會(huì)。朋友們可以做個(gè)小實(shí)驗(yàn),刪除libtest.so,然后輸入./hello。此時(shí)大家可以看看系統(tǒng)有沒有錯(cuò)誤返回? 這個(gè)時(shí)候,有的朋友就會(huì)問了,那在windows下面dll應(yīng)該怎么編寫呢?其實(shí)也不難,只要在test.h上面稍作改變即可。其他的步驟和靜態(tài)庫的操作是基本類似的。

#ifndef _TEST_H #define _TEST_H #ifdef USR_DLL #define DLL_API _declspec(dllexport) #else #define DLL_API _declspec(dllimport) #endif DLL_API int add(int a, int b); #endif

linux下的C語言開發(fā)(定時(shí)器) 定時(shí)器是我們需要經(jīng)常處理的一種資源。那linux下面的定時(shí)器又是怎么一回事呢?其實(shí),在linux里面有一種進(jìn)程中信息傳遞的方法,那就是信號(hào)。這里的定時(shí)器就相當(dāng)于系統(tǒng)每隔一段時(shí)間給進(jìn)程發(fā)一個(gè)定時(shí)信號(hào),我們所要做的就是定義一個(gè)信號(hào)處理函數(shù)。

#include <stdio.h> #include <time.h> #include <sys/time.h> #include <stdlib.h> #include <signal.h> static int count = 0; static struct itimerval oldtv; void set_timer() {struct itimerval itv;itv.it_interval.tv_sec = 1;itv.it_interval.tv_usec = 0;itv.it_value.tv_sec = 1;itv.it_value.tv_usec = 0;setitimer(ITIMER_REAL, &itv, &oldtv); } void signal_handler(int m) {count ++;printf("%d\n", count); } int main() {signal(SIGALRM, signal_handler);set_timer();while(count < 10000);exit(0);return 1; }

linux下的C語言開發(fā)(自動(dòng)編譯工具) 在Linux下面,編寫makefile是一件辛苦的事情。因此,為了減輕程序員編寫makefile的負(fù)擔(dān),人們發(fā)明了autoconf和automake這兩個(gè)工具,可以很好地幫我們解決這個(gè)問題。 我們可以通過一個(gè)簡單的示例來說明如何使用配置工具。

(1)首先,編寫源文件hello.c。

#include <stdio.h> int main(int argc, char** argv[]) {printf("hello, world!\n");return 1; }

(2)接下來,我們需要?jiǎng)?chuàng)建一個(gè)Makefile.am,同時(shí)編寫上腳本。

SUBDIRS= bin_PROGRAMS=hello hello_SOURCES=hello.c

(3)直接輸入autoscan,生成文件configure.scan,再改名為configure.in。修改腳本AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)為AC_INIT(hello, 1.0, feixiaoxing@163.com)同時(shí),在AC_CONFIG_HEADER([config.h])后面添加AM_INIT_AUTOMAKE(hello, 0.1) (4)依次輸入aclocal命令、autoheader命令 (5)創(chuàng)建4個(gè)文件,分別為README、NEWS、AUTHORS和ChangeLog (6)依次輸入automake -a、autoconf命令 (7)輸入./configure,生成最終的Makefile (8)如果需要編譯,輸入make;如果需要安裝, 輸入make install;如果需要發(fā)布軟件包,輸入make dist

linux下的C語言開發(fā)(進(jìn)程創(chuàng)建) 在Linux下面,創(chuàng)建進(jìn)程是一件十分有意思的事情。我們都知道,進(jìn)程是操作系統(tǒng)下面享有資源的基本單位。那么,在Linux下面應(yīng)該怎么創(chuàng)建進(jìn)程呢?其實(shí)非常簡單,一個(gè)fork函數(shù)就可以搞定了。但是,我們需要清楚的是子進(jìn)程與父進(jìn)程之間除了代碼是共享的之外,堆棧數(shù)據(jù)和全局?jǐn)?shù)據(jù)均是獨(dú)立的。

#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> int main() {pid_t pid;if(-1 == (pid = fork())) {printf("Error happened in fork function!\n");return 0;}if(0 == pid) {printf("This is child process: %d\n", getpid());} else {printf("This is parent process: %d\n", getpid());}return 0; }

linux下的C語言開發(fā)(進(jìn)程等待) 所謂進(jìn)程等待,其實(shí)很簡單。前面我們說過可以用fork創(chuàng)建子進(jìn)程,那么這里我們就可以使用wait函數(shù)讓父進(jìn)程等待子進(jìn)程運(yùn)行結(jié)束后才開始運(yùn)行。注意,為了證明父進(jìn)程確實(shí)是等待子進(jìn)程運(yùn)行結(jié)束后才繼續(xù)運(yùn)行的,我們使用了sleep函數(shù)。但是,在linux下面,sleep函數(shù)的參數(shù)是秒,而windows下面sleep的函數(shù)參數(shù)是毫秒。

#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char* argv[]) {pid_t pid;pid = fork();if(0 == pid) {printf("This is child process, %d\n", getpid());sleep(5);} else {wait(NULL);printf("This is parent process, %d\n", getpid());}return 1; }

下面,我們需要做的就是兩步,首先輸入gcc fork.c -o fork, 然后輸入./fork,就會(huì)在console下面獲得這樣的結(jié)果。

[root@localhost fork]# ./fork This is child process, 2135 This is parent process, 2134

linux下的C語言開發(fā)(信號(hào)處理) 信號(hào)處理是linux程序的一個(gè)特色。用信號(hào)處理來模擬操作系統(tǒng)的中斷功能,對于我們這些系統(tǒng)程序員來說是最好的一個(gè)選擇了。要想使用信號(hào)處理功能,你要做的就是填寫一個(gè)信號(hào)處理函數(shù)即可。一旦進(jìn)程有待處理的信號(hào)處理,那么進(jìn)程就會(huì)立即進(jìn)行處理。

#include <stdio.h> #include <stdlib.h> #include <signal.h> int value = 0; void func(int sig) {printf("I get a signal!\n");value = 1; } int main() {signal(SIGINT, func);while(0 == value)sleep(1);return 0; }

為了顯示linux對signal的處理流程,我們需要進(jìn)行兩個(gè)步驟。 第一,輸入gcc sig.c -o sig, 然后輸入./sig即可; 第二則重啟一個(gè)console窗口,輸入ps -aux | grep sig, 在獲取sig的pid之后然后輸入kill -INT 2082, 我們即可得到如下的輸出。

[root@localhost fork]#./sig I get a signal! [root@localhost fork]#

linux下的C語言開發(fā)(管道通信) Linux系統(tǒng)本身為進(jìn)程間通信提供了很多的方式,比如說管道、共享內(nèi)存、socket通信等。管道的使用十分簡單,在創(chuàng)建了匿名管道之后,我們只需要從一個(gè)管道發(fā)送數(shù)據(jù),再從另外一個(gè)管道接受數(shù)據(jù)即可。

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> int pipe_default[2]; int main() {pid_t pid;char buffer[32];memset(buffer, 0, 32);if(pipe(pipe_default) < 0) {printf("Failed to create pipe!\n");return 0;}if(0 == (pid = fork())) {close(pipe_default[1]);sleep(5);if(read(pipe_default[0], buffer, 32) > 0) {printf("Receive data from server, %s!\n", buffer);}close(pipe_default[0]);} else {close(pipe_default[0]);if(-1 != write(pipe_default[1], "hello", strlen("hello"))) {printf("Send data to client, hello!\n");}close(pipe_default[1]);waitpid(pid, NULL, 0);}return 1; }

下面我們就可以開始編譯運(yùn)行了,老規(guī)矩分成兩步驟進(jìn)行: (1)輸入gcc pipe.c -o pipe; (2)然后輸入./pipe,過一會(huì)兒你就可以看到下面的打印了。

[test@localhost pipe]$ ./pipe Send data to client, hello! Receive data from server, hello!

linux下的C語言開發(fā)(多線程編程) 多線程和多進(jìn)程還是有很多區(qū)別的。其中之一就是,多進(jìn)程是linux內(nèi)核本身所支持的,而多線程則需要相應(yīng)的動(dòng)態(tài)庫進(jìn)行支持。對于進(jìn)程而言,數(shù)據(jù)之間都是相互隔離的,而多線程則不同,不同的線程除了堆棧空間之外所有的數(shù)據(jù)都是共享的。說了這么多,我們還是自己編寫一個(gè)多線程程序看看結(jié)果究竟是怎么樣的。

#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> void func_1(void* args) {while(1) {sleep(1);printf("this is func_1!\n");} } void func_2(void* args) {while(1) {sleep(2);printf("this is func_2!\n");} } int main() {pthread_t pid1, pid2;if(pthread_create(&pid1, NULL, func_1, NULL)) {return -1;}if(pthread_create(&pid2, NULL, func_2, NULL)) {return -1;}while(1) {sleep(3);}return 0; }

和我們以前編寫的程序有所不同,多線程代碼需要這樣編譯,輸入gcc thread.c -o thread -lpthread,編譯之后你就可以看到thread可執(zhí)行文件,輸入./thread即可。

[test@localhost Desktop]$ ./thread this is func_1! this is func_2! this is func_1! this is func_1! this is func_2! this is func_1! this is func_1! this is func_2! this is func_1! this is func_1!

linux下的C語言開發(fā)(線程等待) 和多進(jìn)程一樣,多線程也有自己的等待函數(shù)。這個(gè)等待函數(shù)就是pthread_join函數(shù)。那么這個(gè)函數(shù)有什么用呢?我們其實(shí)可以用它來等待線程運(yùn)行結(jié)束。

#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> void func(void* args) {sleep(2);printf("this is func!\n"); } int main() {pthread_t pid;if(pthread_create(&pid, NULL, func, NULL)) {return -1;}pthread_join(pid, NULL);printf("this is end of main!\n");return 0; }

編寫wait.c文件結(jié)束之后,我們就可以開始編譯了。首先你需要輸入gcc wait.c -o wait -lpthread,編譯之后你就可以看到wait可執(zhí)行文件,輸入./wait即可。

[test@localhost thread]$ ./thread this is func! this is end of main!

linux下的C語言開發(fā)(線程互斥) 對于編寫多線程的朋友來說,線程互斥是少不了的。在linux下面,編寫多線程常用的工具其實(shí)是pthread_mutex_t。本質(zhì)上來說,它和Windows下面的mutex其實(shí)是一樣的,差別幾乎是沒有。希望對線程互斥進(jìn)行詳細(xì)了解的朋友可以看這里。

#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> static int value = 0; pthread_mutex_t mutex; void func(void* args) {while(1) {pthread_mutex_lock(&mutex);sleep(1);value ++;printf("value = %d!\n", value);pthread_mutex_unlock(&mutex);} } int main() {pthread_t pid1, pid2;pthread_mutex_init(&mutex, NULL);if(pthread_create(&pid1, NULL, func, NULL)) {return -1;}if(pthread_create(&pid2, NULL, func, NULL)) {return -1;}while(1)sleep(0);return 0; }

編寫mutex.c文件結(jié)束之后,我們就可以開始編譯了。首先你需要輸入gcc mutex.c -o mutex -lpthread,編譯之后你就可以看到mutex可執(zhí)行文件,輸入./mutex即可。

[test@localhost thread]$ ./mutex value = 1! value = 2! value = 3! value = 4! value = 5! value = 6!

linux下的C語言開發(fā)(網(wǎng)絡(luò)編程) 不管在Windows平臺(tái)下面還是在Linux平臺(tái)下面,網(wǎng)絡(luò)編程都是少不了的。在互聯(lián)網(wǎng)發(fā)達(dá)的今天,我們的生活基本上已經(jīng)離不開網(wǎng)絡(luò)了。我們可以用網(wǎng)絡(luò)干很多的事情,比如說IM聊天、FTP下載、電子銀行、網(wǎng)絡(luò)購物、在線游戲、電子郵件的收發(fā)等等。所以說,對于一個(gè)軟件的開發(fā)者來說,如果說他不會(huì)進(jìn)行網(wǎng)絡(luò)程序的開發(fā),那真是難以想象的。

在開始介紹網(wǎng)絡(luò)編程的方法之前,我們可以回憶一下計(jì)算機(jī)網(wǎng)絡(luò)的相關(guān)知識(shí)。目前為止,我們使用的最多網(wǎng)絡(luò)協(xié)議還是tcp/ip網(wǎng)絡(luò)。通常來說,我們習(xí)慣上稱為tcp/ip協(xié)議棧。至于協(xié)議棧分成幾層,有兩種說法。一種是五層,一種是七層,我個(gè)人本身也比較傾向于五層的劃分方法。大家可以通過下面的圖看看協(xié)議棧是怎么劃分的。

5、應(yīng)用層 4、傳輸層 3、網(wǎng)絡(luò)層 2、數(shù)據(jù)鏈路層 1、物理層

網(wǎng)絡(luò)的不同層次實(shí)現(xiàn)網(wǎng)絡(luò)的不同功能。物理層主要實(shí)現(xiàn)報(bào)文的成幀處理;數(shù)據(jù)鏈路層完成對報(bào)文的優(yōu)先級(jí)的管理,同時(shí)實(shí)現(xiàn)二層轉(zhuǎn)發(fā)和流量控制;網(wǎng)絡(luò)層實(shí)現(xiàn)路由和轉(zhuǎn)發(fā)的功能,一方面它需要實(shí)現(xiàn)對報(bào)文的fragment處理,另外一方面它還需要對路由信息進(jìn)行處理和保存;傳輸層實(shí)現(xiàn)報(bào)文的發(fā)送和接受,它利用計(jì)數(shù)、時(shí)序、定時(shí)器、重發(fā)等機(jī)制實(shí)現(xiàn)對報(bào)文的準(zhǔn)確發(fā)送,當(dāng)然這都是tcp的發(fā)送機(jī)制,而udp一般是不保證報(bào)文正確發(fā)送和接收的;應(yīng)用層就是根據(jù)傳輸層的端口信息調(diào)用不同的程序來處理傳輸?shù)膬?nèi)容,端口8080是http報(bào)文,端口21是ftp報(bào)文等等。上面的邏輯稍顯復(fù)雜,朋友們可以這么理解, 物理層關(guān)心的是如何把電氣信號(hào)變成一段報(bào)文;數(shù)據(jù)鏈路層關(guān)心的是mac地址、vlan、優(yōu)先級(jí)等;網(wǎng)絡(luò)層關(guān)心的是ip地址,下一跳ip;傳輸層關(guān)心的是端口資源;應(yīng)用層關(guān)心的是報(bào)文組裝、解析、渲染、存儲(chǔ)、執(zhí)行等等。 目前關(guān)于tcp/ip完整協(xié)議棧的代碼很多,其中我認(rèn)為寫得比較好的還是linux內(nèi)核/net/ipv4下面的代碼。如果朋友們對ipv6的代碼感興趣,也可以看看/net/ipv6的代碼。檔案如果朋友們對整個(gè)協(xié)議棧的代碼結(jié)構(gòu)理解得不是很清楚,可以參考《linux網(wǎng)絡(luò)分析與開發(fā)》這本書。 當(dāng)然,作為應(yīng)用層,我們的其實(shí)考慮的不用這么復(fù)雜。對于網(wǎng)絡(luò)程序編寫人員來講,所有網(wǎng)絡(luò)的資源只要和一個(gè)socket關(guān)聯(lián)在一起就可以了。當(dāng)然在socket可用之前,我們需要為它配置端口信息和ip地址。配置完了之后,我們就可以慢慢等待報(bào)文的收發(fā)了。所以一般來說,作為服務(wù)器端口的處理流程是這樣的, a) 創(chuàng)建socket b) 綁定socket到特定的ip地址 c) 對socket進(jìn)行偵聽處理 d) 接受socket,表明有客戶端和服務(wù)器連接 e) 和客戶端循環(huán)收發(fā)報(bào)文 f) 關(guān)閉socket

作為服務(wù)器程序而言,它要對特定的端口進(jìn)行綁定和偵聽處理,這樣稍顯復(fù)雜。但是如果是編寫客戶端的程序,一切的一切就變得非常簡單了, a) 創(chuàng)建socket b) 鏈接服務(wù)器端地址 c) 和服務(wù)器端的socket收發(fā)報(bào)文

上面只是對網(wǎng)絡(luò)編程做了一個(gè)基本的介紹,但是好多的東西還是沒有涉及到,比如說: (1) 什么時(shí)候該使用udp,什么時(shí)候該使用tcp? (2) 如何把多線程和網(wǎng)絡(luò)編程聯(lián)系在一起? (3) 如何把多進(jìn)程和網(wǎng)絡(luò)編程聯(lián)系在一起? (4) 如何利用select函數(shù)、epoll_create機(jī)制、非阻塞函數(shù)提高socket的并發(fā)處理效率? (5) linux內(nèi)核是怎么實(shí)現(xiàn)tcp/ip協(xié)議的? (6) 我們自己是否也可以實(shí)現(xiàn)協(xié)議的處理流程等等? ———————————————— 版權(quán)聲明:本文為CSDN博主「江湖駭客」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/weixin_40756041/article/details/88112872

以上就是良許教程網(wǎng)為各位朋友分享的Linux相關(guān)知識(shí)。

總結(jié)

以上是生活随笔為你收集整理的linux c 开发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。