1. sem_id = semget(SEM_KEY,0,0); //SEM_KEY自定义,要确保唯一性
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEMKEY 1234L
#define PERMS 0666
struct sembuf op_down[1]={0,-1,0};
struct sembuf op_up[1]={0,1,0};
int semid=-1;
int res;
void init_sem()
{
semid=semget(SEMKEY,1,IPC_CREAT |PERMS);
if(semid<0)
{
printf("create semaphore\n");
semid=semget(SEMKEY,1,IPC_CREAT| PERMS);
if(semid<0)
{
printf("couldn't create semaphore\n");
exit(-1);
}
res=semctl(semid,0,SETVAL,1);
}
}
void down()
{
res=semop(semid,&op_down[0],1);
}
void up()
{
res=semop(semid,&op_up[0],1);
}
int main()
{
init_sem();
printf("beforecritical code\n");
down();
printf("incritical code\n");
sleep(10);
up();
return 0;
}
补充:
下面实例演示了使用shmget函数创建一块共享内存。程序中在调用shmget函数时指定key参数值为IPC_PRIVATE,这个参数的意义是创建一个新的共享内存区,当创建成功后使用shell命令ipcs来显示目前系统下共享内存的状态。命令参数-m为只显示共享内存的状态
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFSZ 4096
int main ( void )
{
int shm_id; /*共享内存标识符*/
shm_id=shmget(IPC_PRIVATE, BUFSZ, 0666 ) ;
if (shm_id < 0 )
{ /*创建共享内存*/
perror( "shmget" ) ;
exit ( 1 );
}
printf ( "successfully created segment : %d \n", shm_id ) ;
system( "ipcs -m"); /*调用ipcs命令查看IPC*/
exit( 0 );
}
输出结果:
root@ubuntu:/zhaoshuyan/process# gcc -o main 1.cpp
root@ubuntu:/zhaoshuyan/process# ./main
successfully created segment : 360457
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 196608 root 777 2783908 2 dest
0x00000000 229377 root 777 17028 2 dest
0x00000000 65538 root 777 20856 2 dest
0x00000000 98307 root 777 20196 2 dest
0x00000000 131076 root 777 23364 2 dest
0x00000000 163845 root 777 97824 2 dest
0x00000000 262150 root 777 26532 2 dest
0x00000000 294919 root 777 19800 2 dest
0x00000000 327688 root 777 25476 2 dest
0x00000000 360457 root 666 4096 0
root@ubuntu:/zhaoshuyan/process#
http://www.cnblogs.com/forstudy/archive/2012/03/26/2413724.html
能够正常运行进程间信号量通信实例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <wait.h>
#define DELAY_TIME 5
int shuyan = 0;
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
// 将信号量sem_id设置为init_value
int init_sem(int sem_id,int init_value)
{
union semun sem_union;
sem_union.val=init_value;
if (semctl(sem_id,0,SETVAL,sem_union)==-1)
{
perror("Sem init");
exit(1);
}
return 0;
}
// 删除sem_id信号量
int del_sem(int sem_id)
{
union semun sem_union;
if (semctl(sem_id,0,IPC_RMID,sem_union)==-1)
{
perror("Sem delete");
exit(1);
}
return 0;
}
// 对sem_id执行p操作
int sem_p(int sem_id)
{
struct sembuf sem_buf;
sem_buf.sem_num=0; //信号量编号
sem_buf.sem_op=-1; //P操作
sem_buf.sem_flg=SEM_UNDO;//系统退出前未释放信号量,系统自动释放
if (semop(sem_id,&sem_buf,1)==-1)
{
perror("Sem P operation");
exit(1);
}
return 0;
}
// 对sem_id执行V操作
int sem_v(int sem_id)
{
struct sembuf sem_buf;
sem_buf.sem_num=0;
sem_buf.sem_op=1; //V操作
sem_buf.sem_flg=SEM_UNDO;
if (semop(sem_id,&sem_buf,1)==-1)
{
perror("Sem V operation");
exit(1);
}
return 0;
}
int main()
{
pid_t pid;
int sem_id;
key_t sem_key;
sem_key=ftok(".",'a');
// 以0666且create mode创建一个信号量,返回给sem_id
sem_id=semget(sem_key,1,0666|IPC_CREAT);
// 将sem_id设为1
init_sem(sem_id,1);
if ((pid=vfork())<0)
{
perror("Fork error!\n");
exit(1);
}
else if (pid==0)
{
sem_p(sem_id); // P操作
printf("Child running...\n");
sleep(DELAY_TIME);
shuyan++;
printf("Child %d,returned value:%d. shuyan = %d\n",getpid(),pid,shuyan);
sem_v(sem_id); // V操作
exit(0);
}
else
{
sem_p(sem_id); // P操作
printf("Parent running!\n");
sleep(5);
shuyan++;
printf("Parent %d,returned value:%d. shuyan = %d\n",getpid(),pid,shuyan);
sem_v(sem_id); // V操作
waitpid(pid,0,0);
del_sem(sem_id);
exit(0);
}
}
首先提一点fork与vfork的区别:fork的父子进程独立使用自己的变量空间。而vfork则共同操作同一变量。同时vfork保证子进程先走。