A. c語言實例,linux線程同步的信號量方式 謝謝
這么高的懸賞,實例放後面。信號量(sem),如同進程一樣,線程也可以通過信號量來實現通信,雖然是輕量級的。信號量函數的名字都以"sem_"打頭。線程使用的基本信號量函數有四個。
信號量初始化。
intsem_init(sem_t*sem,intpshared,unsignedintvalue);
這是對由sem指定的信號量進行初始化,設置好它的共享選項(linux只支持為0,即表示它是當前進程的局部信號量),然後給它一個初始值VALUE。
等待信號量。給信號量減1,然後等待直到信號量的值大於0。
intsem_wait(sem_t*sem);
釋放信號量。信號量值加1。並通知其他等待線程。
intsem_post(sem_t*sem);
銷毀信號量。我們用完信號量後都它進行清理。歸還佔有的一切資源。
intsem_destroy(sem_t*sem);
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#include<errno.h>
#definereturn_if_fail(p)if((p)==0){printf("[%s]:funcerror!/n",__func__);return;}
typedefstruct_PrivInfo
{
sem_ts1;
sem_ts2;
time_tend_time;
}PrivInfo;
staticvoidinfo_init(PrivInfo*thiz);
staticvoidinfo_destroy(PrivInfo*thiz);
staticvoid*pthread_func_1(PrivInfo*thiz);
staticvoid*pthread_func_2(PrivInfo*thiz);
intmain(intargc,char**argv)
{
pthread_tpt_1=0;
pthread_tpt_2=0;
intret=0;
PrivInfo*thiz=NULL;
thiz=(PrivInfo*)malloc(sizeof(PrivInfo));
if(thiz==NULL)
{
printf("[%s]:Failedtomallocpriv./n");
return-1;
}
info_init(thiz);
ret=pthread_create(&pt_1,NULL,(void*)pthread_func_1,thiz);
if(ret!=0)
{
perror("pthread_1_create:");
}
ret=pthread_create(&pt_2,NULL,(void*)pthread_func_2,thiz);
if(ret!=0)
{
perror("pthread_2_create:");
}
pthread_join(pt_1,NULL);
pthread_join(pt_2,NULL);
info_destroy(thiz);
return0;
}
staticvoidinfo_init(PrivInfo*thiz)
{
return_if_fail(thiz!=NULL);
thiz->end_time=time(NULL)+10;
sem_init(&thiz->s1,0,1);
sem_init(&thiz->s2,0,0);
return;
}
staticvoidinfo_destroy(PrivInfo*thiz)
{
return_if_fail(thiz!=NULL);
sem_destroy(&thiz->s1);
sem_destroy(&thiz->s2);
free(thiz);
thiz=NULL;
return;
}
staticvoid*pthread_func_1(PrivInfo*thiz)
{
return_if_fail(thiz!=NULL);
while(time(NULL)<thiz->end_time)
{
sem_wait(&thiz->s2);
printf("pthread1:pthread1getthelock./n");
sem_post(&thiz->s1);
printf("pthread1:pthread1unlock/n");
sleep(1);
}
return;
}
staticvoid*pthread_func_2(PrivInfo*thiz)
{
return_if_fail(thiz!=NULL);
while(time(NULL)<thiz->end_time)
{
sem_wait(&thiz->s1);
printf("pthread2:pthread2gettheunlock./n");
sem_post(&thiz->s2);
printf("pthread2:pthread2unlock./n");
sleep(1);
}
return;
}
B. 在linux c編程中,怎樣判斷該文件為二進制文件用純c來判斷!
下面是文件擴展名的簡要列表和他們的說明:
壓縮和打包文件:
.bz2—bzip2壓縮文件
.gz—gzip壓縮文件
.tar—tar打包文件
.tbz—tar打包並用bzip壓縮的文件
.tgz—tar打包並用gzip壓縮的文件.
文件格式
.au—audio文件
.gif—GIF圖象文件
.html/.htm—HTML文件
.jpg—JPEG圖象文件
.pdf—文檔的電子圖象;PDF代表PortableDocumentFormat
.png—PNG圖象(PortableNetworkGraphic的縮寫)
.ps—PostScript文件;列印格式文件
.txt—純文本文件
.wav—audio文件
.xpm—圖象文件
系統文件
.conf—配置文件
.lock—lock文件;用來判斷一個程序或者設備是否在被使用
.rpm—RedHatPackageManager文件,用來安裝程序,軟體和腳本文件
.c—c源程序代碼文件
.cpp—C 源程序代碼文件
.h—C或者C 程序的頭文件
.o—程序目標文件
.pl—Perl腳本
.so—類庫文件
.tcl—TCL腳本
擴展名 文件類型 打開方式
.aiff 聲音文件 Windows media Player
.!!! Netants 暫存文件 Netants
.ani 動畫滑鼠
.arj 壓縮文件 ARJ
.avi 電影文件 Windows media Player
.awd 傳真文檔
.bak 備份文件
.bas Basic 語言 Basic
.bat DOS批處理文件
.bin MAC 二進制碼文件 Stuffit Expander
.bmp 圖象文件 畫圖/看圖軟體
.cab 壓縮文件 Winzip
.cdr Corel圖畫文件 Corel Draw
.chk Scandisk檢察後製作的文件 可以刪掉
.com DOS命令文件 自執行
.cpx Cryptapix加密圖片文件 Cryptapix
.cur 靜態滑鼠
.dbf 資料庫文件 dBase, FoxBase, Access
.dll 應用程序擴展
.doc 文檔文件 Word
.dwg AutoCAD文件 AutoCAD
.eps Illustrator 圖畫文件 Adobe Illustrator
.exe 執行文件 自執行
.fon 字體文件
.gb 國標碼文件 南極星文字處理
.get Getright 暫存文件
.gif 256色圖象文件 畫圖/看圖軟體
.gz 可供UNIX或LINUX使用的壓縮文件 Winzip
.hqx Macintosh 文件 Stuffit Expander
.htm 網頁 瀏覽器
.html 網頁 瀏覽器
.ico 圖標
.ini 配置設置 筆記本或WordPad
.ipx IPX演示文件 瀏覽器加裝IPX 插件
.jiff 圖象文件 畫圖/看圖軟體
.jpeg 壓縮過的圖象文件 畫圖/看圖軟體
.jpg 壓縮過的圖象文件 畫圖/看圖軟體
.js javascript
.lnk 快捷方式連接文件 連接文件的相應程序
.m3u Winamp播放列表 Winamp
.mid 聲音文件 Windows media Player
.mov Quicktime影像文件 Quick Time
.mp3 壓縮音樂文件 Winamp
.mpeg 影像 Windows media Player
.mpg 影像 Windows media Player
.njx 南極星文檔 南極星文字處理
.pcb 電子電路圖設計文件 Protel PCB
.pdf 攜帶型文檔格式,SupFree0內含圖片文字等等 Adobe Acrobat, Adobe Acrobat Reader
.pm5 PageMaker 5 排版文件 Page Maker
.ppt Power Point 文件 Microsoft Power Point
.ps GhostScript
.psd Photoshop文件 Adobe Photoshop
.pub Publisher排版文件 Microsoft Publisher
.qt Quicktime影像文件 Quick Time
.ra Real Audio聲音文件 Real Audio
.ram Real Audio影像文件 Real Audio
.rar 壓縮文件 Winrar
.rsf Richwin 字體文件
.sch 電子原理圖設計文件 Protel Schematic
.scr 屏保文件
.sea Macintosh 啟動文件
.sit 壓縮 Stuffit Expander
.swf Flash動畫文件 瀏覽器加裝Macromedia flash 插件
.sys 系統文件
.tar UNIX壓縮文件 Winzip
.tif 高質量圖象文件 畫圖/看圖軟體
.tiff 高質量圖象文件 畫圖/看圖軟體
.tmp 暫存文件 可以刪掉
.ttf 字體文件
.txt 純文本文件 筆記本或全部文字處理系統
.vbs Visual Basic 編程文件 Microsoft Viasual Basic
.viv VIVO影像文件 瀏覽器加裝VIVO 插件
.vqf 壓縮聲音文件 Yamaha SoundVQ Player
.wav 未壓縮的聲音文件 Windows media Player
.wk1 Lotus 123 試算軟體文件 Lotus 123, Excel
.wq1 Q-Pro 試算軟體文件 Q-Pro, Excel
.wri Write文字文檔 Word
.xls Excel 試算軟體文件 Microsoft Excel
.Z UNIX壓縮文件 Winzip
.zip 壓縮文件 Winzip
C. linux c內存溢出的core mp bug怎麼跟
淺析Linux下core文件
當我們的程序崩潰時,內核有可能把該程序當前內存映射到core文件里,方便程序員找到程序出現問題的地方。最常出 現的,幾乎所有C程序員都出現過的錯誤就是「段錯誤」了。也是最難查出問題原因的一個錯誤。下面我們就針對「段錯誤」來分析core文件的產生、以及我們 如何利用core文件找到出現崩潰的地方。
何謂core文件
當一個程序崩潰時,在進程當前工作目錄的core文件中復制了該進程的存儲圖像。core文件僅僅是一個內存映象(同時加上調試信息),主要是用來調試的。
當程序接收到以下UNIX信號會產生core文件:
名字
說明
ANSI C POSIX.1
SVR4 4.3+BSD
預設動作
SIGABRT
異常終止(abort)
. .
. .
終止w/core
SIGBUS
硬體故障
.
. .
終止w/core
SIGEMT
硬體故障
. .
終止w/core
SIGFPE
算術異常
. .
. .
終止w/core
SIGILL
非法硬體指令
. .
. .
終止w/core
SIGIOT
硬體故障
. .
終止w/core
SIGQUIT
終端退出符
.
. .
終止w/core
SIGSEGV
無效存儲訪問
. .
. .
終止w/core
SIGSYS
無效系統調用
. .
終止w/core
SIGTRAP
硬體故障
. .
終止w/core
SIGXCPU
超過CPU限制(setrlimit)
. .
終止w/core
SIGXFSZ
超過文件長度限制(setrlimit)
. .
終止w/core
在系統默認動作列,「終止w/core」表示在進程當前工作目錄的core文件中復制了該進程的存儲圖像(該文件名為core,由此可以看出這種功能很久之前就是UNIX功能的一部分)。大多數UNIX調試程序都使用core文件以檢查進程在終止時的狀態。
core文件的產生不是POSIX.1所屬部分,而是很多UNIX版本的實現特徵。UNIX第6版沒有檢查條件 (a)和(b),並且其源代碼中包含如下說明:「如果你正在找尋保護信號,那麼當設置-用戶-ID命令執行時,將可能產生大量的這種信號」。4.3 + BSD產生名為core.prog的文件,其中prog是被執行的程序名的前1 6個字元。它對core文件給予了某種標識,所以是一種改進特徵。
表中「硬體故障」對應於實現定義的硬體故障。這些名字中有很多取自UNIX早先在DP-11上的實現。請查看你所使用的系統的手冊,以確切地確定這些信號對應於哪些錯誤類型。
下面比較詳細地說明這些信號。
• SIGABRT 調用abort函數時產生此信號。進程異常終止。
• SIGBUS 指示一個實現定義的硬體故障。
• SIGEMT 指示一個實現定義的硬體故障。
EMT這一名字來自PDP-11的emulator trap 指令。
• SIGFPE 此信號表示一個算術運算異常,例如除以0,浮點溢出等。
• SIGILL 此信號指示進程已執行一條非法硬體指令。
4.3BSD由abort函數產生此信號。SIGABRT現在被用於此。
• SIGIOT 這指示一個實現定義的硬體故障。
IOT這個名字來自於PDP-11對於輸入/輸出TRAP(input/output TRAP)指令的縮寫。系統V的早期版本,由abort函數產生此信號。SIGABRT現在被用於此。
• SIGQUIT 當用戶在終端上按退出鍵(一般採用Ctrl-\)時,產生此信號,並送至前台進
程組中的所有進程。此信號不僅終止前台進程組(如SIGINT所做的那樣),同時產生一個core文件。
• SIGSEGV 指示進程進行了一次無效的存儲訪問。
名字SEGV表示「段違例(segmentation violation)」。
• SIGSYS 指示一個無效的系統調用。由於某種未知原因,進程執行了一條系統調用指令,
但其指示系統調用類型的參數卻是無效的。
• SIGTRAP 指示一個實現定義的硬體故障。
此信號名來自於PDP-11的TRAP指令。
• SIGXCPU SVR4和4.3+BSD支持資源限制的概念。如果進程超過了其軟C P U時間限制,則產生此信號。
• SIGXFSZ 如果進程超過了其軟文件長度限制,則SVR4和4.3+BSD產生此信號。
摘自《UNIX環境高級編程》第10章 信號。
使用core文件調試程序
看下面的例子:
/*core_mp_test.c*/
#include
const char *str = "test";
void core_test(){
str[1] = 'T';
}
int main(){
core_test();
return 0;
}
編譯:
gcc –g core_mp_test.c -o core_mp_test
如果需要調試程序的話,使用gcc編譯時加上-g選項,這樣調試core文件的時候比較容易找到錯誤的地方。
執行:
./core_mp_test
段錯誤
運行core_mp_test程序出現了「段錯誤」,但沒有產生core文件。這是因為系統默認core文件的大小為0,所以沒有創建。可以用ulimit命令查看和修改core文件的大小。
ulimit -c 0
ulimit -c 1000
ulimit -c 1000
-c 指定修改core文件的大小,1000指定了core文件大小。也可以對core文件的大小不做限制,如:
ulimit -c unlimited
ulimit -c unlimited
如果想讓修改永久生效,則需要修改配置文件,如 .bash_profile、/etc/profile或/etc/security/limits.conf。
再次執行:
./core_mp_test
段錯誤 (core mped)
ls core.*
core.6133
可以看到已經創建了一個core.6133的文件.6133是core_mp_test程序運行的進程ID。
調式core文件
core文件是個二進制文件,需要用相應的工具來分析程序崩潰時的內存映像。
file core.6133
core.6133: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from 'core_mp_test'
在Linux下可以用GDB來調試core文件。
gdb core_mp_test core.6133
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show ing" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
Core was generated by `./core_mp_test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x080482fd in core_test () at core_mp_test.c:7
7 str[1] = 'T';
(gdb) where
#0 0x080482fd in core_test () at core_mp_test.c:7
#1 0x08048317 in main () at core_mp_test.c:12
#2 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6
GDB中鍵入where,就會看到程序崩潰時堆棧信息(當前函數之前的所有已調用函數的列表(包括當前函數),gdb只顯示最近幾個),我們很容易找到我們的程序在最後崩潰的時候調用了core_mp_test.c 第7行的代碼,導致程序崩潰。注意:在編譯程序的時候要加入選項-g。您也可以試試其他命令,如fram、list等。更詳細的用法,請查閱GDB文檔。
core文件創建在什麼位置
在進程當前工作目錄的下創建。通常與程序在相同的路徑下。但如果程序中調用了chdir函數,則有可能改變了當前工 作目錄。這時core文件創建在chdir指定的路徑下。有好多程序崩潰了,我們卻找不到core文件放在什麼位置。和chdir函數就有關系。當然程序 崩潰了不一定都產生core文件。
什麼時候不產生core文件
在下列條件下不產生core文件:
( a )進程是設置-用戶-ID,而且當前用戶並非程序文件的所有者;
( b )進程是設置-組-ID,而且當前用戶並非該程序文件的組所有者;
( c )用戶沒有寫當前工作目錄的許可權;
( d )文件太大。core文件的許可權(假定該文件在此之前並不存在)通常是用戶讀/寫,組讀和其他讀。
利用GDB調試core文件,當遇到程序崩潰時我們不再束手無策。
D. Linux 用C寫串口(modem)(急!)
是的,linux是linus
tovalds當時為了研究一個多用戶多任務操作系統,用c代碼編寫了一個很小的操作系統內核,他把這個源碼公布,大家都來修改它和發展它,最終發展成現在的linux操作系統.
E. 在linux下用c語言實現用多進程同步方法演示「生產者-消費者」問題
這個問題需要的知識主要包括:
1 多進程間進行通信;
2 使用同步信號量(semaphore)和互斥信號量(mutex)進行數據保護。
參考代碼如下,可以參照注釋輔助理解:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#defineN2//消費者或者生產者的數目
#defineM10//緩沖數目
intin=0;//生產者放置產品的位置
intout=0;//消費者取產品的位置
intbuff[M]={0};//緩沖初始化為0,開始時沒有產品
sem_tempty_sem;//同步信號量,當滿了時阻止生產者放產品
sem_tfull_sem;//同步信號量,當沒產品時阻止消費者消費
pthread_mutex_tmutex;//互斥信號量,一次只有一個線程訪問緩沖
intproct_id=0;//生產者id
intprochase_id=0;//消費者id
/*列印緩沖情況*/
voidprint()
{
inti;
for(i=0;i<M;i++)
printf("%d",buff[i]);
printf(" ");
}
/*生產者方法*/
void*proct()
{
intid=++proct_id;
while(1)
{
//用sleep的數量可以調節生產和消費的速度,便於觀察
sleep(1);
//sleep(1);
sem_wait(&empty_sem);
pthread_mutex_lock(&mutex);
in=in%M;
printf("proct%din%d.like: ",id,in);
buff[in]=1;
print();
++in;
pthread_mutex_unlock(&mutex);
sem_post(&full_sem);
}
}
/*消費者方法*/
void*prochase()
{
intid=++prochase_id;
while(1)
{
//用sleep的數量可以調節生產和消費的速度,便於觀察
sleep(1);
//sleep(1);
sem_wait(&full_sem);
pthread_mutex_lock(&mutex);
out=out%M;
printf("prochase%din%d.like: ",id,out);
buff[out]=0;
print();
++out;
pthread_mutex_unlock(&mutex);
sem_post(&empty_sem);
}
}
intmain()
{
pthread_tid1[N];
pthread_tid2[N];
inti;
intret[N];
//初始化同步信號量
intini1=sem_init(&empty_sem,0,M);
intini2=sem_init(&full_sem,0,0);
if(ini1&&ini2!=0)
{
printf("seminitfailed ");
exit(1);
}
//初始化互斥信號量
intini3=pthread_mutex_init(&mutex,NULL);
if(ini3!=0)
{
printf("mutexinitfailed ");
exit(1);
}
//創建N個生產者線程
for(i=0;i<N;i++)
{
ret[i]=pthread_create(&id1[i],NULL,proct,(void*)(&i));
if(ret[i]!=0)
{
printf("proct%dcreationfailed ",i);
exit(1);
}
}
//創建N個消費者線程
for(i=0;i<N;i++)
{
ret[i]=pthread_create(&id2[i],NULL,prochase,NULL);
if(ret[i]!=0)
{
printf("prochase%dcreationfailed ",i);
exit(1);
}
}
//銷毀線程
for(i=0;i<N;i++)
{
pthread_join(id1[i],NULL);
pthread_join(id2[i],NULL);
}
exit(0);
}
在Linux下編譯的時候,要在編譯命令中加入選項-lpthread以包含多線程支持。比如存儲的C文件為demo.c,要生成的可執行文件為demo。可以使用命令:
gcc demo.c -o demo -lpthread
程序中為便於觀察,使用了sleep(1);來暫停運行,所以查看輸出的時候可以看到,輸出是每秒列印一次的。