精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
1.开发平台Linux,gcc编译
2.本程序简单演示了IPC高级进程间的通信,
3.同时打开多个终端进程,按任意键立即打印出运行时间 最长的进程id,按CTRL^C退出
4.所涉技术共享内存和信号量配合使用,线程的使用等
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <sys/sem.h>
struct procliveinfo //先定义共享内存的结构
{
int count;
int cstatus[100];
int ipid[100];
};
union semun//使用sem,要自己定义这个结构
{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
#define PI_LEN sizeof(struct procliveinfo) //共享内存结构的长度
struct procliveinfo *pshm=NULL;
time_t starttm, runtm;
void writetm(void)
{
time_t tnow;
while(1)
{
time(&tnow);
runtm=tnow-starttm;
pshm->cstatus[pshm->count]=runtm;
sleep(1);
}
}
int main(int argc,char*argv[])
{
int shmid,rct,tmpcount,i,iMax=0,iPlaceMax=0;
int semid;
pthread_t pid;
union semun sem_union;
struct sembuf buffer;
buffer.sem_num = 0;
buffer.sem_flg = SEM_UNDO;
time(&starttm);
shmid=shmget((key_t)23,PI_LEN,0666|IPC_CREAT); //共享内存的创建
pshm=shmat(shmid,0,0);
if(pshm->count>=100)//达到数组上限,则进程退出
{
printf("count > 100\n");
exit(1);
}
semid = semget((key_t)26,1,0666|IPC_CREAT); //信号量集创建
sem_union.val = 1;
semctl (semid,0,SETVAL,sem_union);//信号量初始化,1表示同一个时刻只有一个进程有权限使用资源
buffer.sem_op = -1;//加锁,保证count没问题,执行p(sem)p操作
semop (semid, &buffer, 1);
tmpcount=pshm->count;
pshm->ipid[tmpcount]=getpid();
pshm->count++;
buffer.sem_op = 1;//解锁,执行v(sem)v操作
semop (semid, &buffer, 1);
rct=pthread_create(&pid,NULL,(void*)writetm,NULL);//线程创建
if(rct!=0)
{
perror("creatthread error\n");
exit(1);
}
while(1)
{
getchar();//等待键盘动作
buffer.sem_op = -1;//加锁,执行p(sem)p操作
semop (semid, &buffer, 1);
tmpcount=pshm->count;
iMax=pshm->cstatus[0];
for(i=0;i<tmpcount;i++)//找最大值
{
if(pshm->cstatus[i]>iMax)
{
iMax=pshm->cstatus[i];
iPlaceMax=i;
}
}
//根据找到的最大值位置进行输出
printf("count:%d pid:%d runtime=%d\n",iPlaceMax,
pshm->ipid[iPlaceMax],
pshm->cstatus[iPlaceMax]);
buffer.sem_op = 1;
semop (semid, &buffer, 1);//解锁,执行v(sem)v操作
}
pthread_join(pid,NULL);//回收线程
shmdt(pPrinfo);//脱离共享内存
shmctl(shmid,IPC_RMID,0);//删除共享内存
return 0;
}