linux進程信號
Ⅰ linux系統的進程間通信有哪幾種方式
一、方式
1、管道(Pipe)及有名管道( mkpipe):
管道可用於具有親緣關系進程間的通信,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關系進程間的通信;
2、信號(Signal):
信號是比較復雜的通信方式,用於通知接受進程有某種事件發生,除了用於進程間通信外,進程還可以發送信號給進程本身。
linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction。
實際上,該函數是基於BSD的,BSD為了實現可靠信號機制,又能夠統一對外介面,用sigaction函數重新實現了signal函數。
3、消息隊列(Message):
消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。有足夠許可權的進程可以向隊列中添加消息,被賦予讀許可權的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式位元組流以及緩沖區大小受限等缺點。
4、共享內存:
使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設計的。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。
5、信號量(semaphore):
主要作為進程間以及同一進程不同線程之間的同步手段。
6、套介面(Socket):
更為一般的進程間通信機制,可用於不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和System V的變種都支持套接字。
二、概念
進程間通信概念:
IPC—-InterProcess Communication
每個進程各自有不同的用戶地址空間,任何一個進程的全局變數在另一個進程中都看不到所以進程之間要交換數據必須通過內核。
在內核中開辟一塊緩沖區,進程1把數據從用戶空間拷到內核緩沖區,進程2再從內核緩沖區把數據讀走,內核提供的這種機制稱為進程間通信。
(1)linux進程信號擴展閱讀
1)無名管道:
管道是半雙工的,數據只能向一個方向流動;需要雙方通信時,需要建立起兩個管道;只能用於父子進程或者兄弟進程之間(具有親緣關系的進程)。
管道對於管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬於某種文件系統,構成兩進程間通信的一個媒介。
數據的讀出和寫入:一個進程向管道中寫的內容被管道另一端的進程讀出。寫入的內容每次都添加在管道緩沖區的末尾,並且每次都是從緩沖區的頭部讀出數據。
2)有名管道:
不同於管道之處在於它提供一個路徑名與之關聯,以FIFO的文件形式存在於文件系統中。這樣,即使與FIFO的創建進程不存在親緣關系的進程,只要可以訪問該路徑,就能夠彼此通過FIFO相互通信(能夠訪問該路徑的進程以及FIFO的創建進程之間)。
因此,通過FIFO不相關的進程也能交換數據。值得注意的是,FIFO嚴格遵循先進先出(first in first out),對管道及FIFO的讀總是從開始處返回數據,對它們的寫則把數據添加到末尾。它們不支持諸如lseek()等文件定位操作。
Ⅱ linux中的信號怎麼理解
linux的常用信號量BUS與SEGV二者都是錯誤信號,BUS表示匯流排錯誤,SEGV表示段錯誤,程序崩潰的時候99%都是這兩個錯誤導致的。進程可以捕獲和封鎖這兩類錯誤。內核對二者的默認處理是memorympWINCH窗口改變信號(WINdownCHanged)。例如虛擬終端的行數發生變化時將發送WINCH信號,絕大多數文本編輯器都能捕獲WINCH信號自動進行重新配置。內核的默認處理是忽略該信號,並且不進行內存轉儲。進程可以捕獲或者封鎖該信號KILL 殺死/刪除進程,編號為9STOP 掛起/暫停正在執行的進程,直到收到CONT為止KILLSTOP都不能夠被捕獲、封鎖或者忽略,默認處理都不會產生內存轉儲。CONT 取消掛起,繼續執行進程TSTP 是STOP信號的「軟」版本,即在用戶輸入Ctrl+Z時由終端驅動程序發送的信號。捕獲到該信號的進程通常清除它們的狀態,如何給自己發送一個STOP信號。TSTP的默認處理不會導致內存轉儲。INT 中斷信號,編號為2當用戶輸入Ctrl+C時由終端驅動程序發送INT信號INT信號是終止當前操作的請求,簡單程序捕獲到INT信號時應該退出,擁有命令行或者輸入模式的那些程序應該停止他們正在做的事情,清除狀態,並等待用戶再次輸入。TERM 軟體終止信號,編號為15TERM是請求徹底終止某項操作的信號,它期望進程清楚自己的狀態並退出QUIT 退出信號,編號為3與TERM類似,不同之處在於QUIT信號的默認處理是內存轉儲,而TERM信號的默認處理沒有內存轉儲。HUP 掛起信號,編號為1,有兩種解釋:守護進程理解HUP為重新設置的請求,如果守護進程能夠不用重新啟動就能夠重新讀取它自己的配置文件並調整自己以適應變化的話,那麼HUP信號通常可以用來觸發這種行為HUP信號有時有終端驅動程序生成,試圖用來清除(也就是終止)跟某個特定終端相連接的那些進程。例如當一個終端會話結束時,或者當一個Modem的連接不經意的斷開時,就可能出現這種情況。如果需要某些進程在會話結束之後繼續運行,那麼在CShell中設法讓這些進程變成後台程序,ksh或者bash中可以用nohup來模擬這種行為。++++++++++++++++++++++++++++++++++++++++++++++++++++++++++進程的四種狀態runnable(可運行狀態)只要有CPU時間,進程就可以執行。一旦進程執行了不能立即完成的系統調用,Linux會把進程轉入睡眠狀態sleeping(睡眠狀態)進程在等待某些事件發生(如終端輸入、網路連接)zombie(僵化狀態)進程已經執行完畢並試圖消亡,但是狀態沒有收集完stopped(停止狀態)進程被掛起,不允許執行。進程收到STOP或者TSTP信號即進入停止狀態,可以用CONT信號來重新啟動
Ⅲ linux 多進程信號同步問題
線程的最大特點是資源的共享性,但資源共享中的同步問題是多線程編程的難點。linux下提供了多種方式來處理線程同步,最常用的是互斥鎖、條件變數和信號量。
1)互斥鎖(mutex)
通過鎖機制實現線程間的同步。同一時刻只允許一個線程執行一個關鍵部分的代碼。
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex *mutex);
int pthread_mutex_destroy(pthread_mutex *mutex);
int pthread_mutex_unlock(pthread_mutex *
(1)先初始化鎖init()或靜態賦值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER
attr_t有:
PTHREAD_MUTEX_TIMED_NP:其餘線程等待隊列
PTHREAD_MUTEX_RECURSIVE_NP:嵌套鎖,允許線程多次加鎖,不同線程,解鎖後重新競爭
PTHREAD_MUTEX_ERRORCHECK_NP:檢錯,與一同,線程請求已用鎖,返回EDEADLK;
PTHREAD_MUTEX_ADAPTIVE_NP:適應鎖,解鎖後重新競爭
(2)加鎖,lock,trylock,lock阻塞等待鎖,trylock立即返回EBUSY
(3)解鎖,unlock需滿足是加鎖狀態,且由加鎖線程解鎖
(4)清除鎖,destroy(此時鎖必需unlock,否則返回EBUSY,//Linux下互斥鎖不佔用內存資源
Ⅳ 簡述Linux進程間通信的幾種方式
進程間通訊進程間通信就是不同進程之間傳播或交換信息,進程的用戶空間是互相獨立的,進程之間可以利用系統空間交換信息。
管道(pipe)管道是一種半雙工的通信方式,數據只能單向流動。如果要進行雙工通信,需要建立兩個管道。
管道只能在具有親緣關系的進程間使用,例如父子進程或兄弟進程。
有名管道(named
pipe)
有名管道也是雙半工的通信方式,但它允許無親緣關系的進程間使用。
信號量(semophore)
信號量常用來作為一種鎖機制來使用,它是一個記數器,用來控制多進程對共享資源的訪問,防止多個進程同時訪問一個共享資源。信號量主要用作為進程間或同一進程間不同線程之間的同步手段。
信號(sinal)
信號是一種比較復雜的通信方式,用於通知接收進程某些事件已經發生,要注意信號處理中調用的函數是否為信號安全。
消息隊列(message
queue)
消息隊列是由消息的鏈表組成,存放在內核中並由消息隊列標識符標識。
共享內存(shared
memory)
共享內存就是映射一段被其他進程所訪問的內存,這段共享內存由一個進程創建,可由多個進程訪問。共享內存是最快的IPC方式,它是針對其他進程間通信方式的低運行效率而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
套接字(socket)
套接字也是進程間通信的一種方式,與其他方式不同的是,它可以用在不同主機間的進程通信(也是它的主要用途)。
幾種方式的缺點
管道:
速度慢,容量有限,只能用於親緣關系進程間通信。
有名管道:
同管道,不過允許無親緣關系進程間通信。
消息隊列:
容量受系統限制,隊列中會遺留數據,讀時要考慮到這些未讀完的數據。
信號量:
主要用於同步,無法傳遞復雜的數據信息。
Ⅳ 請教一個Linux下C語言的進程間的信號問題
linux中的進程通信分為三個部分:低級通信,管道通信和進程間通信IPC(inter process communication)。linux的低級通信主要用來傳遞進程的控制信號——文件鎖和軟中斷信號機制。linux的進程間通信IPC有三個部分——①信號量,②共享內存和③消息隊列。以下是我編寫的linux進程通信的C語言實現代碼。操作系統為redhat9.0,編輯器為vi,編譯器採用gcc。下面所有實現代碼均已經通過測試,運行無誤。
一.低級通信--信號通信
signal.c
#include
#include
#include
/*捕捉到信號sig之後,執行預先預定的動作函數*/
void sig_alarm(int sig)
{
printf("---the signal received is %d. /n", sig);
signal(SIGINT, SIG_DFL); //SIGINT終端中斷信號,SIG_DFL:恢復默認行為,SIN_IGN:忽略信號
}
int main()
{
signal(SIGINT, sig_alarm);//捕捉終端中斷信號
while(1)
{
printf("waiting here!/n");
sleep(1);
}
return 0;
}
二.管道通信
pipe.c
#include
#define BUFFER_SIZE 30
int main()
{
int x;
int fd[2];
char buf[BUFFER_SIZE];
char s[BUFFER_SIZE];
pipe(fd);//創建管道
while((x=fork())==-1);//創建管道失敗時,進入循環
/*進入子進程,子進程向管道中寫入一個字元串*/
if(x==0)
{
sprintf(buf,"This is an example of pipe!/n");
write(fd[1],buf,BUFFER_SIZE);
exit(0);
}
/*進入父進程,父進程從管道的另一端讀出剛才寫入的字元串*/
else
{
wait(0);//等待子進程結束
read(fd[0],s,BUFFER_SIZE);//讀出字元串,並將其儲存在char s[]中
printf("%s",s);//列印字元串
}
return 0;
}
三.進程間通信——IPC
①信號量通信
sem.c
#include
#include
#include
#include types.h>
#include ipc.h>
#include sem.h>
/*聯合體變數*/
union semun
{
int val; //信號量初始值
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
/*函數聲明,信號量定義*/
static int set_semvalue(void); //設置信號量
static void del_semvalue(void);//刪除信號量
static int semaphore_p(void); //執行P操作
static int semaphore_v(void); //執行V操作
static int sem_id; //信號量標識符
int main(int argc, char *argv[])
{
int i;
int pause_time;
char op_char = 'O';
srand((unsigned int)getpid());
sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);//創建一個信號量,IPC_CREAT表示創建一個新的信號量
/*如果有參數,設置信號量,修改字元*/
if (argc > 1)
{
if (!set_semvalue())
{
fprintf(stderr, "Failed to initialize semaphore/n");
exit(EXIT_FAILURE);
}
op_char = 'X';
sleep(5);
}
for(i = 0; i < 10; i++)
{
/*執行P操作*/
if (!semaphore_p())
exit(EXIT_FAILURE);
printf("%c", op_char);
fflush(stdout);
pause_time = rand() % 3;
sleep(pause_time);
printf("%c", op_char);
fflush(stdout);
/*執行V操作*/
if (!semaphore_v())
exit(EXIT_FAILURE);
pause_time = rand() % 2;
sleep(pause_time);
}
printf("/n%d - finished/n", getpid());
if (argc > 1)
{
sleep(10);
del_semvalue(); //刪除信號量
}
exit(EXIT_SUCCESS);
}
/*設置信號量*/
static int set_semvalue(void)
{
union semun sem_union;
sem_union.val = 1;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
return(0);
return(1);
}
/*刪除信號量*/
static void del_semvalue(void)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
fprintf(stderr, "Failed to delete semaphore/n");
}
/*執行P操作*/
static int semaphore_p(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_p failed/n");
return(0);
}
return(1);
}
/*執行V操作*/
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_v failed/n");
return(0);
}
return(1);
}
②消息隊列通信
send.c
#include
#include
#include
#include
#include
#include types.h>
#include ipc.h>
#include msg.h>
#define MAX_TEXT 512
/*用於消息收發的結構體--my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[MAX_TEXT];
};
int main()
{
int running = 1;//程序運行標識符
struct my_msg_st some_data;
int msgid;//消息隊列標識符
char buffer[BUFSIZ];
/*創建與接受者相同的消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
/*向消息隊列中發送消息*/
while(running)
{
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
some_data.my_msg_type = 1;
strcpy(some_data.some_text, buffer);
if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed/n");
exit(EXIT_FAILURE);
}
if (strncmp(buffer, "end", 3) == 0)
{
running = 0;
}
}
exit(EXIT_SUCCESS);
}
receive.c
#include
#include
#include
#include
#include
#include types.h>
#include ipc.h>
#include msg.h>
/*用於消息收發的結構體--my_msg_type:消息類型,some_text:消息正文*/
struct my_msg_st
{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running = 1;//程序運行標識符
int msgid; //消息隊列標識符
struct my_msg_st some_data;
long int msg_to_receive = 0;//接收消息的類型--0表示msgid隊列上的第一個消息
/*創建消息隊列*/
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if (msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
/*接收消息*/
while(running)
{
if (msgrcv(msgid, (void *)&some_data, BUFSIZ,msg_to_receive, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error: %d/n", errno);
exit(EXIT_FAILURE);
}
printf("You wrote: %s", some_data.some_text);
if (strncmp(some_data.some_text, "end", 3) == 0)
{
running = 0;
}
}
/*刪除消息隊列*/
if (msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed/n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
③共享內存通信
share.h
#define TEXT_SZ 2048 //申請共享內存大小
struct shared_use_st
{
int written_by_you; //written_by_you為1時表示有數據寫入,為0時表示數據已經被消費者提走
char some_text[TEXT_SZ];
};
procer.c
#include
#include
#include
#include
#include types.h>
#include ipc.h>
#include shm.h>
#include "share.h"
int main()
{
int running = 1; //程序運行標志位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid; //共享內存標識符
/*創建共享內存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed/n");
exit(EXIT_FAILURE);
}
/*將共享內存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個位元組的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed/n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X/n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
/*生產者寫入數據*/
while(running)
{
while(shared_stuff->written_by_you == 1)
{
sleep(1);
printf("waiting for client.../n");
}
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
shared_stuff->written_by_you = 1;
if (strncmp(buffer, "end", 3) == 0)
{
running = 0;
}
}
/*該函數用來將共享內存從當前進程中分離,僅使得當前進程不再能使用該共享內存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed/n");
exit(EXIT_FAILURE);
}
printf("procer exit./n");
exit(EXIT_SUCCESS);
}
customer.c
#include
#include
#include
#include
#include types.h>
#include ipc.h>
#include shm.h>
#include "share.h"
int main()
{
int running = 1;//程序運行標志位
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid; //共享內存標識符
srand((unsigned int)getpid());
/*創建共享內存*/
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed/n");
exit(EXIT_FAILURE);
}
/*將共享內存連接到一個進程的地址空間中*/
shared_memory = shmat(shmid, (void *)0, 0);//指向共享內存第一個位元組的指針
if (shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed/n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X/n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
shared_stuff->written_by_you = 0;
/*消費者讀取數據*/
while(running)
{
if (shared_stuff->written_by_you)
{
printf("You wrote: %s", shared_stuff->some_text);
sleep( rand() % 4 );
shared_stuff->written_by_you = 0;
if (strncmp(shared_stuff->some_text, "end", 3) == 0)
{
running = 0;
}
}
}
/*該函數用來將共享內存從當前進程中分離,僅使得當前進程不再能使用該共享內存*/
if (shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed/n");
exit(EXIT_FAILURE);
}
/*將共享內存刪除,所有進程均不能再訪問該共享內存*/
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "shmctl(IPC_RMID) failed/n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
摘自:
Ⅵ linux 下進程間通過信號進行通信的具體實現過程
kill函數用來發送信號給指定的進程,在Shell下輸入man 2 kill可獲取其函數原型如下:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid,int sig);
該函數的行為與第一個參數pid的取值有關,第二個參數sig表示信號編號。
如果pid是正數,則發送信號sig給進程號為pid的進程;
如果pid為0,則發送信號sig給當前進程所屬進程組里的所有進程;
如果pid為-1,則把信號sig廣播至系統內除1號進程(init進程)和自身以外的所有進程;
如果pid是-1還小的負數,則發送信號sig給屬於進程組-pid的所有進程。
如果參數sig是0,則kill()仍執行正常的錯誤檢查,但不發送信號。可以利用這一點來確定某進程是否有權向另外一個進程發送信號。如果向一個並不存在的進程發送空信號,則kill()返回-1,errno則被設置為ESRCH。
函數執行成功返回0,當有錯誤發生時則返回-1,錯誤代碼存入errno中,詳細的錯誤代碼說明請參考man手冊。
注意:只有具有root許可權的進程才能向其他任一進程發送信號,非root許可權的進程只能向屬於同一個組或同一個用戶的進程發送信號。
更簡單的方法是通過進程名給進程發信號。比如你的進程名是 aproc,你自己定義一個信號量18,那麼:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char cmd[256]=""; int sig = 18;
char procname[]="aproc";
sprintf(cmd, "killall -%d %s\n", sig, procname);
system(cmd);
就能給特定進程發信號了
充分利用system函數,可以簡化很多編程工作量,比如查IP地址、查硬碟目錄、查磁碟空間等等,編程很麻煩的事都能用system處理,相當於在程序里調用SHELL
Ⅶ linux系統下進程的信號處理流程是怎麼樣的
kill函數用來發送信號給指定的進程,在Shell下輸入man 2 kill可獲取其函數原型如下: #include <sys/types.h> #include <signal.h> int kill(pid_t pid,int sig); 該函數的行為與第一個參數pid的取值有關,第二個參數sig表示信號編號。 如果pid是正數,則發送信號sig給進程號為pid的進程; 如果pid為0,則發送信號sig給當前進程所屬進程組里的所有進程; 如果pid為-1,則把信號sig廣播至系統內除1號進程(init進程)和自身以外的所有進程; 如果pid是-1還小的負數,則發送信號sig給屬於進程組-pid的所有進程。 如果參數sig是0,則kill()仍執行正常的錯誤檢查,但不發送信號。可以利用這一點來確定某進程是否有權向另外一個進程發送信號。如果向一個並不存在的進程發送空信號,則kill()返回-1,errno則被設置為ESRCH。 函數執行成功返回0,當有錯誤發生時則返回-1,錯誤代碼存入errno中,詳細的錯誤代碼說明請參考man手冊。 注意:只有具有root許可權的進程才能向其他任一進程發送信號,非root許可權的進程只能向屬於同一個組或同一個用戶的進程發送信號。 更簡單的方法是通過進程名給進程發信號。比如你的進程名是 aproc,你自己定義一個信號量18,那麼: #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> char cmd[256]=""; int sig = 18; char procname[]="aproc"; sprintf(cmd, "killall -%d %s\n", sig, procname); system(cmd); 就能給特定進程發信號了 充分利用system函數,可以簡化很多編程工作量,比如查IP地址、查硬碟目錄、查磁碟空間等等,編程很麻煩的事都能用system處理,相當於在程序里調用SHELL
Ⅷ linux進程可以向自己發信號嗎
kill函數用來發送信號給指定的進程,在Shell下輸入man 2 kill可獲取其函數原型如下:#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid,int sig);
該函數的行為與第一個參數pid的取值有關,第二個參數sig表示信號編號。
如果pid是正數,則發送信號sig給進程號為pid的進程;
如果pid為0,則發送信號sig給當前進程所屬進程組里的所有進程;
如果pid為-1,則把信號sig廣播至系統內除1號進程(init進程)和自身以外的所有進程;
如果pid是-1還小的負數,則發送信號sig給屬於進程組-pid的所有進程。
如果參數sig是0,則kill()仍執行正常的錯誤檢查,但不發送信號。可以利用這一點來確定某進程是否有權向另外一個進程發送信號。如果向一個並不存在的進程發送空信號,則kill()返回-1,errno則被設置為ESRCH。
函數執行成功返回0,當有錯誤發生時則返回-1,錯誤代碼存入errno中,詳細的錯誤代碼說明請參考man手冊。
注意:只有具有root許可權的進程才能向其他任一進程發送信號,非root許可權的進程只能向屬於同一個組或同一個用戶的進程發送信號。
更簡單的方法是通過進程名給進程發信號。比如你的進程名是 aproc,你自己定義一個信號量18,那麼:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char cmd[256]=""; int sig = 18;
char procname[]="aproc";
sprintf(cmd, "killall -%d %s\n", sig, procname);
system(cmd);
就能給特定進程發信號了
充分利用system函數,可以簡化很多編程工作量,比如查IP地址、查硬碟目錄、查磁碟空間等等,編程很麻煩的事都能用system處理,相當於在程序里調用SHELL
Ⅸ Linux進程間通信的方式有哪些
第一種:管道通信
兩個進程利用管道進行通信時,發送信息的進程稱為寫進程;接收信息的進程稱為讀進程。管道通信方式的中間介質就是文件,通常稱這種文件為管道文件,它就像管道一樣將一個寫進程和一個讀進程連接在一起,實現兩個進程之間的通信。寫進程通過寫入端往管道文件中寫入信息;讀進程通過讀出端從管道文件中讀取信息。兩個進程協調不斷地進行寫和讀,便會構成雙方通過管道傳遞信息的流水線。
第二種:消息緩沖通信
多個獨立的進程之間可以通過消息緩沖機制來相互通信。這種通信的實現是以消息緩沖區為中間介質,通信雙方的發送和接收操作均以消息為單位。在存儲器中,消息緩沖區被組織成隊列,通常稱之為消息隊列。消息隊列一旦創建後即可由多進程共享,發送消息的進程可以在任意時刻發送任意個消息到指定的消息隊列上,並檢查是否有接收進程在等待它所發送的消息。若有則喚醒它,而接收消息的進程可以在需要消息的時候到指定的消息隊列上獲取消息,如果消息還沒有到來,則轉入睡眠等待狀態。
第三種:共享內存通信
針對消息緩沖需要佔用CPU進行消息復制的缺點,OS提供了一種進程間直接進行數據交換的通信方式。共享內存,顧名思義這種通信方式允許多個進程在外部通信協議或同步,互斥機制的支持下使用同一個內存段進行通信,它是一種最有效的數據通信方式,其特點是沒有中間環節,直接將共享的內存頁面通過附接映射到相互通信的進程各自的虛擬地址空間中,從而使多個進程可以直接訪問同一個物理內存頁面。
Ⅹ linux 如何查看進程信號狀態
這個在設置裡面你直接就可以找到,然後查看到他的狀態