/* Message queue control operation. */externintmsgctl(int__msqid,int__cmd,structmsqid_ds*__buf)__THROW;/* Get messages queue. */externintmsgget(key_t__key,int__msgflg)__THROW;/* Receive message from message queue.
This function is a cancellation point and therefore not marked with
__THROW. */externssize_tmsgrcv(int__msqid,void*__msgp,size_t__msgsz,longint__msgtyp,int__msgflg);/* Send message to message queue.
This function is a cancellation point and therefore not marked with
__THROW. */externintmsgsnd(int__msqid,constvoid*__msgp,size_t__msgsz,int__msgflg);
/* Send signal SIG to process number PID. If PID is zero,
send SIG to all processes in the current process's process group.
If PID is < -1, send SIG to all processes in process group - PID. */#ifdef __USE_POSIX
externintkill(__pid_t__pid,int__sig)__THROW;#endif /* Use POSIX. *//* Set the handler for the signal SIG to HANDLER, returning the old
handler, or SIG_ERR on error.
By default `signal' has the BSD semantic. */extern__sighandler_tsignal(int__sig,__sighandler_t__handler)__THROW;
这里简单介绍两个, kill用于发送信号, signal用于处理信号.
发送信号
1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>#include<signal.h>#include<stdlib.h>intmain(intargc,char*argv[]){intsigno=SIGUSR1;intpid=atoi(argv[1]);kill(pid,signo);printf("send sig %d to pid %d\n",signo,pid);}
#include<stdio.h>#include<signal.h>#include<stdlib.h>voidsignalPorcessor(intsigno){printf("process %d receive signal %d\n",getpid(),signo);}intmain(){printf("current pid %d\n",getpid());signal(SIGUSR1,signalPorcessor);while(1){printf("process %d doing something\n",getpid());sleep(1);}}
接收端的信号处理函数和接收端是在同一个进程:
1
2
3
4
5
6
7
8
9
current pid 15273process 15273 doing something
process 15273 doing something
process 15273 doing something
process 15273 doing something
process 15273 doing something
process 15273 receive signal -1943753024
process 15273 doing something
process 15273 doing something
/* The following System V style IPC functions implement a shared memory
facility. The definition is found in XPG4.2. *//* Shared memory control operation. */externintshmctl(int__shmid,int__cmd,structshmid_ds*__buf)__THROW;/* Get shared memory segment. */externintshmget(key_t__key,size_t__size,int__shmflg)__THROW;/* Attach shared memory segment. */externvoid*shmat(int__shmid,constvoid*__shmaddr,int__shmflg)__THROW;/* Detach shared memory segment. */externintshmdt(constvoid*__shmaddr)__THROW;
/* Semaphore control operation. */externintsemctl(int__semid,int__semnum,int__cmd,...)__THROW;/* Get semaphore. */externintsemget(key_t__key,int__nsems,int__semflg)__THROW;/* Operate on semaphore. */externintsemop(int__semid,structsembuf*__sops,size_t__nsops)__THROW;
semget 用于获取或者创建信号量, 输入SEM_KEY参数和信号量数目以及权限flag
semop 用于对信号量的基本操作, 可以执行+1或者-1操作
semctl 用于对信号量的基本控制, 包括初始化, 移除等
semop中的sembuf定义如下:
1
2
3
4
5
6
structsembuf{unsignedshortintsem_num;/* semaphore number */shortintsem_op;/* semaphore operation */shortintsem_flg;/* operation flag */};
/* The user should define a union like the following to use it for arguments
for `semctl'.
union semun
{
int val; <= value for SETVAL
struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
unsigned short int *array; <= array for GETALL & SETALL
struct seminfo *__buf; <= buffer for IPC_INFO
};
Previous versions of this file used to define this union but this is
incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
one must define the union or not. */#define _SEM_SEMUN_UNDEFINED 1
$ ./write & ./write 1& ./write 2& ./write 3[1]16970[2]16971[3]16973shm key 7777 id 1867816, sem key 8888 id 10[16970]write msg: NUHUWAWMIXYSWZZLVBED
shm key 7777 id 1867816, sem key 8888 id 10[16971]write msg: NWLRBBMQBHCDARZOWKKY
shm key 7777 id 1867816, sem key 8888 id 10[16973]write msg: EBGNHAMDHNUXBVZLUFPK
shm key 7777 id 1867816, sem key 8888 id 10[16976]write msg: GVWQTYSKRGSEDLWPMVFX
[16970]write msg: ZHFMVCTSCFVPBCKYDIMN
[16971]write msg: HIDDQSCDXRJMOWFRXSJY
[16973]write msg: KSNBVDSSSJDWKKJUMXXT
[16976]write msg: RAEATJRJUUYASWSLVKYO
[16970]write msg: HLGEMFRJIYMIHRWCVPUX
[16971]write msg: BLDBEFSARCBYNECDYGGX
[16973]write msg: NTSOORAIYRSLLIMGNHAF
[16976]write msg: SQSVCRNOMSNFSRGLCZWW
[16970]write done[16973]write done[16971]write done[16976]write done[1] Done ./write
[2]- Done ./write 1[3]+ Done ./write 2
这是符合预期的, 如果我们删除unlock操作, 则会发现, 进程会卡住:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ ./write & ./write 1& ./write 2& ./write 3[1]20832[2]20833[3]20834shm key 7777 id 1867816, sem key 8888 id 11[20832]write msg: EXOIWWVYGLJNJUAKPSLZ
shm key 7777 id 1867816, sem key 8888 id 11[20833]write msg: NWLRBBMQBHCDARZOWKKY
shm key 7777 id 1867816, sem key 8888 id 11[20834]write msg: EBGNHAMDHNUXBVZLUFPK
shm key 7777 id 1867816, sem key 8888 id 11[20835]write msg: GVWQTYSKRGSEDLWPMVFX
// 卡在这