1. 程式人生 > >程序控制程式設計----------(Linux---C)

程序控制程式設計----------(Linux---C)

1、為什麼程序間需要通訊?
  • 資料傳輸:一個程序需要將它的資料傳送給另一個程序。
  • 資源共享:多個程序之間共享同樣的資源
  • 通知事件:一個程序需要向另一個或一組程序傳送訊息,通知它們發生了某種事件。
  • 程序控制:有些程序希望完全控制另一個程序的執行(如Debug程序),此時控制程序希望能夠攔截另一個程序的所有操作,
並能夠及時知道它的狀態改變。
2、Linux程序間通訊(IPC)由以下幾部分發展而來:
  • UNIX程序間通訊
  • 基於System V程序間通訊
  • POSIX程序間通訊
(1)POSIX
POSIX(Portable Operating System Interface)表示可移植作業系統介面。電氣和電子工程師協會(Institute of Electrical and Electronics
Engineers,IEEE)最初開發POSIX 標準,是為了提高UNIX 環境下應用程式的可移植性。然而,POSIX 並不侷限於UNIX,許多其它的操作
系統,例如DEC OpenVMS 和MicrosoftWindows,都支援POSIX 標準。
(2)System V
System V,也被稱為AT&T System V,是Unix作業系統眾多版本中的一支

3、現在Linux使用的程序間通訊方式包括:

  • 1、管道(pipe)和有名管道(FIFO)
  • 2、訊號(signal)
  • 3、訊息佇列
  • 4、共享記憶體
  • 5、訊號量
  • 6、套接字(socket)

(1)管道通訊
管道是單向的、先進先出的,它把一個程序的輸出和另一個程序的輸入連線在一起。一個程序(寫程序)在管道的尾部寫入資料,另一個程序(讀程序)從管道的頭部讀出資料。

資料被一個程序讀出後,將被從管道中刪除,其它讀程序將不能再讀到這些資料。管道提供了簡單的流控制機制,程序試圖讀空管道時,程序將阻塞。同樣,管道已經滿時,程序再試圖向管道寫入資料,程序將阻塞。

管道建立
管道包括無名管道和有名管道兩種,前者用於父程序和子程序間的通訊,後者可用於運行於同一系統中的任意兩個程序間的通訊。

無名管道由pipe()函式建立:
int pipe(int filedis[2]);
當一個管道建立時,它會建立兩個檔案描述符:filedis[0] 用於讀管道, filedis[1] 用於寫管道


管道關閉
關閉管道只需將這兩個檔案描述符關閉即可,可以使用普通的close函式逐個關閉

示例1、

#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int pipe_fd[2];
if(pipe(pipe_fd)<0)
{
printf("pipe create error\n");
return -1;
}
else
printf("pipe create success\n");
close(pipe_fd[0]);
close(pipe_fd[1]);
}

管道讀寫

管道用於不同程序間通訊。通常先建立一個管道,再通過fork函式建立一個子程序,該子程序會繼承父程序所建立的管道。


注意事項:必須在系統呼叫fork( )前呼叫pipe( ),否則子程序將不會繼承檔案描述符。

例項分析:pipe_rw.c

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

int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char* p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r));
/*建立管道*/
if(pipe(pipe_fd)<0)
{
printf("pipe create error\n");
return -1;
}
/*建立子程序*/
if((pid=fork())==0)  //子程序執行序列
{
printf("\n");
close(pipe_fd[1]);//子程序先關閉了管道的寫端
sleep(2); /*讓父程序先執行,這樣父程序先寫子程序才有內容讀*/
if((r_num=read(pipe_fd[0],buf_r,100))>0)
{
printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
}close(pipe_fd[0]);
exit(0);
}
else if(pid>0) //父程序執行序列
{
close(pipe_fd[0]); //父程序先關閉了管道的讀端
if(write(pipe_fd[1],"Hello",5)!=-1)
printf("parent write1 Hello!\n");
if(write(pipe_fd[1]," Pipe",5)!=-1)
printf("parent write2 Pipe!\n");
close(pipe_fd[1]);
waitpid(pid,NULL,0); /*等待子程序結束*/
exit(0);
}
return 0;
}

(2)命名管道(FIFO)

命名管道和無名管道基本相同,但也有不同點:無名管道只能由父子程序使用;但是通過命名管道,不相關的程序也能交換資料。

建立

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char * pathname, mode_t mode)
  • pathname:FIFO檔名
  • mode:屬性(見檔案操作章節)

一旦建立了一個FIFO,就可用open開啟它,一般的檔案訪問函式(close、read、write等)都可用於FIFO。

操作

當開啟FIFO時,非阻塞標誌(O_NONBLOCK)將對以後的讀寫產生如下影響:
1、沒有使用O_NONBLOCK:訪問要求無法滿足時程序將阻塞。如試圖讀取空的FIFO,將導致程序阻塞。
2、使用O_NONBLOCK:訪問要求無法滿足時不阻塞,立刻出錯返回,errno是ENXIO。

例項分析:fifo_write.c和fifo_read.c

fifo_write.c程式碼:

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"int main(int argc,char** argv)
{
int fd;
char w_buf[100];
int nwrite;
    /*建立有名管道*/
if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL|O_RDWR)<0)&&(errno!=EEXIST))
printf("cannot create fifoserver\n");/*開啟管道*/
fd=open(FIFO_SERVER,O_RDWR|O_NONBLOCK,0);
if(fd==-1)
{
    perror("open");
exit(1);
}
/*入參檢測*/
if(argc==1)
{
printf("Please send something\n");
exit(-1);
}
strcpy(w_buf,argv[1]);
/* 向管道寫入資料 */
if((nwrite=write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf("The FIFO has not been read yet.Please try later\n");
}
else 
printf("write %s to the FIFO\n",w_buf);
close(fd); //關閉管道
return 0;
}


fifo_read.c程式碼:
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo"

int main(int argc,char** argv)
{
char buf_r[100];
int  fd;
int  nread;

printf("Preparing for reading bytes...\n");
memset(buf_r,0,sizeof(buf_r));
/* 開啟管道 */
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);}
while(1)
{
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1)
{
if(errno==EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",buf_r);
sleep(1);
}
//後面三句話是不會被執行到的,但不會影響程式執行的效果當程式在上面的死迴圈中執行時收到訊號後會馬上結束執行而沒有執行後面的三句話。這些會在後面的訊號處理中講到,現在不理解沒有關係,這個問題留給大家學習了訊號處理之後來解決。
close(fd); //關閉管道
pause(); /*暫停,等待訊號*/
unlink(FIFO);//刪除檔案
}

(3)訊號通訊
訊號(signal)機制是Unix系統中最為古老的進程間通訊機制,很多條件可以產生一個訊號:
1、當用戶按某些按鍵時,產生訊號。
2、硬體異常產生訊號:除數為0、無效的儲存訪問等等。這些情況通常由硬體檢測到,將其通知核心,然後核心產生適當的訊號通知程序,例如,核心對正訪問一個無效儲存區的程序產生一個SIGSEGV訊號。

3、程序用kill函式將訊號傳送給另一個程序。
4、使用者可用kill命令將訊號傳送給其他程序。

訊號型別
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR213) SIGPIPE 14) SIGALRM 15) SIGTERM
17) SIGCHLD 18) SIGCONT 19) SIGSTOP20) SIGTSTP 21) SIGTTIN 22) SIGTTOU
23) SIGURG 24) SIGXCPU 25) SIGXFSZ26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR

下面是幾種常見的訊號:

  •  SIGHUP:從終端上發出的結束訊號
  •  SIGINT:來自鍵盤的中斷訊號(Ctrl-C)
  •  SIGKILL:該訊號結束接收訊號的程序
  • SIGTERM:kill 命令發出的訊號
  • SIGCHLD:標識子程序停止或結束的訊號
  •  SIGSTOP:來自鍵盤(Ctrl-Z)或除錯程式的停止執行訊號

訊號處理

當某訊號出現時,將按照下列三種方式中的一種進行處理:
1、忽略此訊號
大多數訊號都按照這種方式進行處理,但有兩種訊號卻決不能被忽略。它們是:SIGKILL和SIGSTOP。這兩種

訊號不能被忽略的原因是:它們向超級使用者提供了一種終止或停止程序的方法。

2、執行使用者希望的動作通知核心在某種訊號發生時,呼叫一個使用者函式。在使用者函式中,執行使用者希望的處理。
3、執行系統預設動作對大多數訊號的系統預設動作是終止該程序。

訊號傳送
傳送訊號的主要函式有kill和raise。
區別:
Kill既可以向自身傳送訊號,也可以向其他程序傳送訊號。與kill函式不同的是,raise函式是向程序自身傳送訊號。

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signo)
int raise(int signo)

kill的pid引數有四種不同的情況:
1、pid>0
將訊號傳送給程序ID為pid的程序。
2、pid == 0
將訊號傳送給同組的程序。
3、pid < 0
將訊號傳送給其程序組ID等於pid絕對值的程序。
4、pid ==-1
將訊號傳送給所有程序。

Alarm
使用alarm函式可以設定一個時間值(鬧鐘時間),當所設定的時間到了時,產生SIGALRM訊號。如果不捕捉此訊號,則預設動作是終止該程序。

#include <unistd.h>
unsigned int alarm(unsigned int seconds)
  • Seconds:經過了指定的seconds秒後會產生訊號SIGALRM。
  • 每個程序只能有一個鬧鐘時間。如果在呼叫alarm時,以前已為該程序設定過鬧鐘時間,而且它還沒有超時,以前登記的鬧鐘時間則被新值代換。
  • 如果有以前登記的尚未超過的鬧鐘時間,而這次seconds值是0,則表示取消以前的鬧鐘。
pause

pause函式使呼叫程序掛起直至捕捉到一個訊號。

#include <unistd.h>
int pause(void)
只有執行了一個訊號處理函式後,掛起才結束。

訊號的處理
 當系統捕捉到某個訊號時,可以忽略該訊號或是使用指定的處理函式來處理該訊號,或者使用系統預設的方式。
 訊號處理的主要方法有兩種,一種是使用簡單的signal函式,另一種是使用訊號集函式組。

signal

#include <signal.h>
void (*signal (int signo, void (*func)(int)))(int)
如何理解?
typedef void (*sighandler_t)(int)
sighandler_t signal(int signum, sighandler_t handler))
Func可能的值是:
1、SIG_IGN:忽略此訊號
2、SIG_DFL: 按系統預設方式處理
3、訊號處理函式名:使用該函式處理

例項分析:mysignal.c

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void my_func(int sign_no)
{
if(sign_no==SIGINT)
printf("I have get SIGINT\n");
else if(sign_no==SIGQUIT)
printf("I have get SIGQUIT\n");
}
int main()
{
printf("Waiting for signal SIGINT or SIGQUIT\n");
/*註冊訊號處理函式*/
signal(SIGINT,my_func);
signal(SIGQUIT,my_func);
pause();
exit(0);}

(4)共享記憶體
共享記憶體是被多個程序共享的一部分實體記憶體。共享記憶體是程序間共享資料的一種最快的方法,一個程序向共享記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。


共享記憶體實現分為兩個步驟:
一、建立共享記憶體,使用shmget函式。
二、對映共享記憶體,將這段建立的共享記憶體對映到具體的程序空間去,使用shmat函式。

建立

int shmget ( key_t key, int size, int shmflg )
key標識共享記憶體的鍵值: 0/IPC_PRIVATE。當key的取值為IPC_PRIVATE,則函式shmget()將建立一塊新的共享記憶體;如果key的取值為0,而引數shmflg中又設定IPC_PRIVATE這個標誌,則同樣會建立一塊新的共享記憶體。
返回值:如果成功,返回共享記憶體識別符號;如果失敗,返回-1。
對映
int shmat ( int shmid, char *shmaddr, int flag)
引數:
  • shmid:shmget函式返回的共享儲存識別符號
  • flag:決定以什麼方式來確定對映的地址(通常為0)
返回值:
如果成功,則返回共享記憶體對映到程序中的地址;如果失敗,則返回- 1。


當一個程序不再需要共享記憶體時,需要把它從程序地址空間中脫離。

int shmdt ( char *shmaddr )
例項分析:shmem.c(演示)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>


#define PERM S_IRUSR|S_IWUSR
/*共享記憶體*/
int main(int argc,char **argv)
{
int shmid;
char *p_addr,*c_addr;
if(argc!=2)
{
fprintf(stderr,"Usage:%s\n\a",argv[0]);
exit(1);
}
/*建立共享記憶體*/
if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1)
{
fprintf(stderr,"Create share Memory Error:%s\n\a",
strerror(errno));
exit(1);
}
/*建立子程序*/
if(fork())//父程序寫
{
p_addr=shmat(shmid,0,0);
memset(p_addr,'\0',1024);
strncpy(p_addr,argv[1],1024);
wait(NULL);//釋放資源,不關心終止狀態
exit(0);
}
else//子程序讀
{
sleep(1);//暫停1秒
c_addr=shmat(shmid,0,0);
printf("Client get %s\n",c_addr);
exit(0);
}


}

程序間通訊程式設計-2

1、訊息佇列

unix早期通訊機制之一的訊號能夠傳送的資訊量有限,管道則只能傳送無格式的位元組流,這無疑會給應用程式開發帶來不便。訊息佇列(也叫做報文佇列)則克服了這些缺點。

訊息佇列就是一個訊息的連結串列。可以把訊息看作一個記錄,具有特定的格式。程序可以向中按照一定的規則新增新消
息;另一些程序則可以從訊息佇列中讀走訊息。

目前主要有兩種型別的訊息佇列:POSIX訊息佇列以及系統V訊息佇列,系統V訊息佇列目前被大量使用。

持續性
系統V訊息佇列是隨核心持續的,只有在核心重起或者人工刪除時,該訊息佇列才會被刪除。

鍵值
訊息佇列的核心持續性要求每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得一個訊息佇列的描述字,必須提供該訊息佇列的鍵值。

(1)鍵值
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok (char*pathname, char proj)
功能:返回檔名對應的鍵值。
pathname:檔名
proj:專案名(不為0即可)

(2)開啟/建立

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg)
key:鍵值,由ftok獲得。
msgflg:標誌位。
返回值:與健值key相對應的訊息佇列描述字。
  • IPC_CREAT:建立新的訊息佇列
  • IPC_EXCL:與IPC_CREAT一同使用,表示如果要建立的訊息佇列已經存在,則返回錯誤。
  • IPC_NOWAIT:讀寫訊息佇列要求無法得到滿足時,不阻塞。
建立
在以下兩種情況下,將建立一個新的訊息佇列:
  • 如果沒有與健值key相對應的訊息佇列,並且msgflg中包含了IPC_CREAT標誌位。
  • key引數為IPC_PRIVATE。
int open_queue(key_t keyval)
{
int qid;
if((qid=msgget(keyval,IPC_CREAT))==-1)
{
return(-1);
}
return(qid);
}

(3)傳送訊息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid,struct msgbuf*msgp,int msgsz,int msgflg)
功能:向訊息佇列中傳送一條訊息。
  •  msqid:已開啟的訊息佇列id
  •  msgp:存放訊息的結構
  •  msgsz:訊息資料長度
  • msgflg:傳送標誌,有意義的msgflg標誌為IPC_NOWAIT,指明在訊息佇列沒有足夠空間容納要傳送的訊息時,msgsnd是否等待。
訊息格式
struct msgbuf
{
long mtype; /* 訊息型別> 0 */
 char mtext[1];   /* 訊息資料的首地址*/
};
(4)接收訊息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int
msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg)
功能:從msqid代表的訊息佇列中讀取一個msgtyp型別的訊息,並把訊息儲存在msgp指向的msgbuf結構中。在成功地讀取了一條訊息以後,佇列中的這條訊息將被刪除。
int read_message(int qid,long type,struct mymsgbuf*qbuf)
{
int result,length;
length=sizeof(struct mymsgbuf)-sizeof(long);
if((result=msgrcv(qid,qbuf,length,type,0))==-1)
return(-1);
return(result);
}
例項分析:msg.c(演示)
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
struct msg_buf
{
int mtype;
char data[255];
};
int main()
{
key_t key;
int msgid;
int ret;
struct msg_buf msgbuf;
key=ftok("/tmp/2",'a');
printf("key=[%x]\n",key);
msgid=msgget(key,IPC_CREAT|0666);//通過檔案對應
if(msgid==-1)
{
printf("create error\n");
return -1;
}
msgbuf.mtype=getpid();
strcpy(msgbuf.data,"test haha");
ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);
if(ret==-1)
{
printf("send message err\n");
return -1;
}
memset(&msgbuf,0,sizeof(msgbuf));
ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);
if(ret==-1)
{
printf("recv message err\n");
return -1;
}
printf("recv msg=[%s]\n",msgbuf.data);
}


2、訊號量
訊號量(又名:訊號燈)與其他程序間通訊方式不大相同,主要用途是保護臨界資源。程序可以根據它判定是否能夠訪問某些共享資源。除了用於訪問控制外,還可用於程序同步。

分類:

  • 二值訊號燈:訊號燈的值只能取0或1,類似於互斥鎖。但兩者有不同:訊號燈強調共享資源,只要共享資源可用,其他程序同樣可以修改訊號燈的值;互斥鎖更強調程序,佔用資源的程序使用完資源後,必須由程序本身來解鎖。
  • 計數訊號燈:訊號燈的值可以取任意非負值。

(1)建立/開啟
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg)
  • key:鍵值,由ftok獲得
  • nsems:指定開啟或者新建立的訊號燈集中將包含訊號燈的數目
  • semflg:標識,同訊息佇列
(2)操作
int semop(int semid, struct sembuf *sops, unsigned nsops)
功能:對訊號量進行控制。
  • semid:訊號量集的ID
  • sops:是一個運算元組,表明要進行什麼操作
  • nsops:sops所指向的陣列的元素個數。
struct sembuf 
{
unsigned short sem_num; /* semaphoreindex in array */
short sem_op;        /* semaphore operation */
short sem_flg;                       /* operation flags */
};
  • sem_num:要操作的訊號量在訊號量集中的編號,第一個訊號的編號是0。
  • sem_op:如果其值為正數,該值會加到現有的訊號量值中,通常用於釋放訊號量;如果sem_op的值為負數,而其絕對值又大於訊號的現值,操作將會阻塞,直到訊號值大於或等於sem_op的絕對值,通常用於獲取訊號量;如果sem_op的值為0,則操作將暫時阻塞,直到訊號的值變為0。
  • Sem_flg:訊號操作標誌,可能的選擇有兩種: IPC_NOWAIT:對訊號的操作不能滿足時,semop()不會阻塞,並立即返回,同時設定錯誤資訊;IPC_UNDO:程式結束時(不論正常或不正常)釋放訊號量,這樣做的目的在於避免程式在異常情況下結束時未將鎖定的資源解鎖,造成該資源永遠鎖定。

相關推薦

程序控制程式設計----------Linux---C

1、為什麼程序間需要通訊?資料傳輸:一個程序需要將它的資料傳送給另一個程序。資源共享:多個程序之間共享同樣的資源通知事件:一個程序需要向另一個或一組程序傳送訊息,通知它們發生了某種事件。程序控制:有些程序希望完全控制另一個程序的執行(如Debug程序),此時控制程序希望能夠攔截另一個程序的所有操作,並能夠及時

基於TCP的伺服器端/客戶端---------網路程式設計Linux----C

基於TCP的伺服器端/客戶端(二)---網路程式設計(Linux--C) 在基於TCP的伺服器端/客戶端(一)中的回聲客戶端存在的問題: 下列是echo_client.c中的程式碼: write(so

獲取磁盤使用率Linux C

磁盤 pen open get 獲取 code can per sent #define SYS_DISK_BUFF_LEN 256 #define SYS_DISK_NAME_LEN 80 #define SYS_100_PERSENT 100 int get_sysDi

獲取系統cpu使用率linux C

user 系統 def can get gets 數組名 結構體 lin typedef struct cpu_occupy_ //定義一個cpu occupy的結構體 { char name[20]; //定義

獲取內存使用率Linux C

sscanf fopen fgets roc 獲取 ota scan 1.0 def #define SYS_MEM_NAME_LEN 20 #define SYS_MEM_BUFF_LEN 256 #define SYS_100_PERSENT 100 int get_

牛客網——2017校招真題線上程式設計python&C++

牛客網——2017校招真題線上程式設計(python&C++)題目描述找出n個數裡最小的k個輸入描述:每個測試輸入包含空格分割的n+1個整數,最後一個整數為k值,n 不超過100。輸出描述:輸出

時間函式和定時執行緒linux C

1.日期時間輸出格式: printf("%04d-%02d-%02d\n",year,month,day); 輸出:1994-02-07  d表示輸出整數、2表示寬度、0表示不足兩位前面補0,右對齊。 2.signal函式: signal(SIGALRM,statis

Linux C 程序控制筆記

一、程序 程序是一個動態實體,是程式的一次執行過程,是作業系統資源分配的基本單位。程序是執行中的程式,程式是一些儲存在硬碟上的可執行程式碼。 二、程序結構 Linux中程序由三部分組成:程式碼段,資料段,堆疊段 程式碼段(存放可執行程式碼) 資料段(存放程式全域性

Linux C語言程式設計上篇 | gcc的使用

嵌入式軟體開發主要使用C語言開發,編譯過程稱為交叉編譯 —— 在PC機上編譯出可以在嵌入式處理器上執行的程式,在真正進入嵌入式開發前,先來了解下如何使用gcc+make編譯C語言工程,如何用gdb除錯工程~ 1.C程式設計流程 1.1.編輯原始檔(.c) 使用文字編輯器(比如vi

Linux程序控制Processing Control Block

程序 在廣義上,所有的程序資訊被放在一個叫做程序控制塊的資料結構中,可以理解為程序屬性 的集合。 程序控制塊 每個程序在核心中都有一個程序控制塊(PCB)來維護程序相關的資訊,Linux核心的 程序控制塊是task_struct結構體。現在我們全面瞭解

學習Linux C程式設計程序控制程式設計

建立程序 fork fork 的定義 在 Linux 中,我們使用 fork 來建立一個子程序 fork 的返回值 fork 函式有些特殊,成功它返回 2 次,失敗返回 -1,利用這個特性可以判斷當前的程序是子程序還是父程序:  1. 在子程序中返回 0  2.

【嵌入式Linux C程式設計Linux程序控制程式設計

程序是一個具有一定獨立功能的程式的一次執行活動,同時也是資源分配的最小單元。程序的生命週期:        建立:每個程序可以由父程序建立,程序可以建立子程序,子程序可以建立孫程序。        執行:多個程序可以同時存在,程序間可以通訊。        撤銷:程序可以撤銷

Linux程序程式設計-之二-程序間通訊訊息佇列

1.1         系統V訊息佇列 訊息佇列中的每個訊息都有如下的資料結構: struct msgbuf { long mtype;         // 訊息型別 char mtext[n];      // 訊息內容,n由使用者自己定義 }; 1.1.1      

【閱讀筆記】《C程序員 從校園到職場》第三章 程序的樣式大括號

突出 char s 結構體 需要 初始化 detail 處理 思維 https 參考: https://blog.csdn.net/zhouzhaoxiong1227/article/details/22820533 一、.初始化數組變量 在實際的軟件開

程序間通訊之Linux C管道程式設計

管道簡述 管道(pipe)是Unix/Linux中最常見的程序間通訊方式之一,它在兩個程序之間實現一個數據流通的通道,資料以一種資料流的方式在程序間流動。在系統中,管道相當於檔案系統上的一個檔案,用於快取所要傳輸的資料。在某些特性上又不同於檔案,例如當資料讀出後,管道中就沒有資料了,但檔案沒

解決Linux下網路程式設計sendto send 出現 SIGPIPE 訊號導致程式異常終止的問題

引言 最近在Linux下網路程式設計時,出現SIGPIPE 訊號導致程式異常終止,本文記錄下解決的方法以及相應的知識。 SIGPIPE 訊號資料 什麼時候出現此訊號,APUE中有關此訊號的解釋如下: Linux man手冊有關此訊號的解釋: man 7 signal SI

Linux程序之如何檢視程序詳情?ps命令

文章目錄 1. ps是什麼? 2. 不加引數執行ps命令會輸出什麼? 3. 如何顯示所有當前程序? 4. 如何根據程序的使用者進行資訊過濾呢? 5. 如何通過cpu和記憶體使用來過濾程序? 5.1 根據CPU使用率

C# 新增Excel表單控制元件Form Controls

在Excel中,新增的控制元件可以和單元格關聯,我們可以操作控制元件來修改單元格的內容,在下面的文章中,將介紹在Excel中新增幾種不同的表單控制元件的方法,包括:  新增文字框(Textbox)  單選按鈕(Radio button)  複選框(Checkbox

多執行緒設計linux c pthread_mutex_trylock和pthread_mutex_lock

1.問題:理想情況下有兩條執行緒,一條執行緒不斷插入佇列,一條執行緒不斷取出佇列,兩條執行緒是併發執行的,但實驗階段的現象卻是第一條執行緒全部插入佇列後第二條執行緒才會開始取 (1)執行緒一: pt

java-socket簡單程式設計socket C/S加解密

好久沒更新部落格了,最近在幫老師整理專案,本來對socket接觸的不多。本次不多說廢話,直接說專案 專案要求:1.實現服務端和客戶端的傳輸檔案加解密,我這邊實現的是服務端傳輸加密後的檔案,客戶端收到檔案後解密,為了展示方便,我此次採用了AES加密方式,填充方式採用AES/C