linux下c语言编程4使用共享内存实现进程间通信Word文件下载.docx
《linux下c语言编程4使用共享内存实现进程间通信Word文件下载.docx》由会员分享,可在线阅读,更多相关《linux下c语言编程4使用共享内存实现进程间通信Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
printf("
createsharedmemoryOK.shmid=%d/n"
shmid);
return0;
}
进程B代码如下:
intmain(intargc,char*argv[])
{
intshmid;
char*shmaddr;
if(argc!
=2)
{
perror("
argcerror/n"
shmid=atoi(argv[1]);
shmaddr=(char*)shmat(shmid,NULL,0);
if((int)shmaddr==-1)
shmaterror./n"
}
strcpy(shmaddr,"
hello,world!
"
shmdt(shmaddr);
}
进程C代码如下:
char*shmaddr;
if(argc!
%s/n"
shmaddr);
进程D代码如下:
shmctl(shmid,IPC_RMID,NULL);
return0;
linux下C语言编程5-多线程编程
Linux系统下的多线程遵循POSIX线程接口,称为pthread。
编写Linux下的多线程程序,需要使用头文件pthread.h,编译需要在后面加-lpthread。
关于多线程,主要有以下几个过程:
1,创建线程
2,各个线程的执行
3,等待线程的结束
涉及的线程函数主要有:
1,intpthread_create(pthread_t*restricttidp,constpthread_attr_t*restrictattr,void*(*start_rtn)(void),
void*restrictarg);
函数有4个参数:
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是一个函数指针(有关函数指针,看这里),指向线程运行函数的起始地址。
最后一个参数是函数指针所需要的参数。
注意:
pthread_create函数返回0表示成功。
另外如果函数指针需要多个参数的话,就将这些参数做成某个结构体,作为第4个参数。
如果有返回值的话,也可将返回值的指针回写到第4个参数中。
2,pthread_join()等待一个线程的结束。
pthread_exit()用于线程退出,可以指定返回值,以便其他线程通过pthread_join()函数获取该线程的返回值。
线程的应用:
并行数据库的查询
假设我们有3台计算机A,B,C,每台均安装PG数据库,通过网络连接。
我们可以通过多线程将查询SQL广播出去,A,B,C并行查询,最终返回各自的结果。
如果没有多线程,而只是用了个循环,那么我们获取结果的过程将是顺序的,即等A的结果返回后才能查询B,B结束后查询C,效率低下。
代码如下:
//最多支持MAX个线程#defineMAX16
/****多线程******/
typedefstructPDthread
char*host;
//IP
intport;
//端口
char*dbname;
//数据库名
char*query;
//SQL语句
void*rst;
//查询结果
}PDthread;
typedefstructNodes
intcount;
//实际上的节点数量count<
=MAX
charhost[MAX][32];
intport[MAX];
}Nodes;
/*线程的执行过程,参数m为PDthread结构*/
void*PDthreadSelect(void*m)
PDthread*p=(PDthread*)m;
p->
rst=(void*)ExecuteQuery(p->
host,p->
port,p->
dbname,p->
query);
pthread_exit(NULL);
returnNULL;
}/*创建多个线程,1个node对应1个线程*输出:
thread[],pdthread*输入:
node,dbname,query,这些值写到pdthread变量中,传递给函数PDthreadSelect(因为此函数只能有一个参数)*/
voidPDthreadCreate(pthread_tthread[],PDthread*pdthread,Nodes*node,char*dbname,char*query)
inttmp;
inti;
PDthread*p;
for(i=0;
i<
node->
count;
i++)
//把Nodes作为PDthread的一部分
p=pdthread+i;
host=node->
host[i];
p->
port=node->
port[i];
dbname=dbname;
query=query;
tmp=pthread_create(&
thread[i],NULL,PDthreadSelect,p);
if(tmp!
=0)printf("
PDthreadCreate:
线程%d创建失败!
/n"
i);
elseprintf("
线程%d被创建/n"
voidPDthreadWait(pthread_tthread[],intcount)
//等待线程结束
for(i=0;
i++)
{
if(thread[i]!
=0)
pthread_join(thread[i],NULL);
printf("
线程%d已经结束/n"
}
Nodesnode;
node.count=3;
strcpy(node.host[0],"
192.168.0.1"
node.port[0]=5432;
strcpy(node.host[1],"
192.168.0.2"
node.port[1]=5432;
strcpy(node.host[2],"
192.168.0.3"
node.port[2]=5432;
//使用多线程去获取数据
pthread_tthread[MAX];
memset(&
thread,0,sizeof(thread));
//获取结果
PDthread*pdthread=(PDthread*)malloc(node.count*sizeof(PDthread));
PDthreadCreate(thread,pdthread,&
node,"
database"
"
SELECT*FROMstudent"
PDthreadWait(thread,node.count);
//返回结果存储在pdthread->
rst
编译命令:
gcc-I/usr/local/pgsql/include-othth.c-L/usr/local/pgsql/lib-lpq-lpthread,因为使用了libpq库。
Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现(Linux环境下C编程指南)
Linux环境下C编程指南,通过共享内存进行进程间通信的例子,进程间同步使用信号量来实现。
使用说明:
这是一个简单的服务器和客户端程序,如果启动程序时不带参数,则执行服务器程序;
如果带参数,则执行客户端程序,所带参数只有一个,就是服务器端所显示的共享内存的引用ID。
实现原理:
服务器端启动后,创建信号量和共享内存,并将共享内存的引用ID显示出来,将信号量
的引用ID存放在共享内存中。
客户端启动后,利用服务器端提供的内存共享ID将共享内存附加到地址段,读取信号量以实现两个进程之间的同步。
之后,这两个进程就可以利用共享内存进行进程间通信,客户端输入的信息将在服务器端显示出来。
#include<
stdlib.h>
errno.h>
string.h>
signal.h>
stdio.h>
sys/types.h>
sys/sem.h>
#defineSHMDATASIZE1000
#defineBUFFERSIZE(SHMDATASIZE-sizeof(int))
#defineSN_EMPTY0
#defineSN_FULL1
intdeleteSemid=0;
unionsemun
intval;
structsemid_ds*buf;
unsignedshortint*array;
structseminfo*__buf;
};
voidserver(void);
//不加参数时执行
voidclient(intshmid);
voiddelete(void);
voidsigdelete(intsignum);
voidlocksem(intsemid,intsemnum);
voidunlocksem(intsemid,intsemnum);
voidwaitzero(intsemid,intsemnum);
voidclientwrite(intshmid,intsemid,char*buffer);
intsafesemget(key_tkey,intnsems,intsemflg);
intsafesemctl(intsemid,intsemnum,intcmd,unionsemunarg);
intsafesemop(intsemid,structsembuf*sops,unsignednsops);
intsafeshmget(key_tkey,intsize,intshmflg);
void*safeshmat(intshmid,constvoid*shmaddr,intshmflg);
intsafeshmctl(intshmid,intcmd,structshmid_ds*buf);
intmain(intargc,char*argv[])
if(argc<
2)
server();
}
else
client(atoi(argv[1]));
voidserver(void)
unionsemunsunion;
intsemid,shmid;
void*shmdata;
char*buffer;
semid=safesemget(IPC_PRIVATE,2,SHM_R|SHM_W);
deleteSemid=semid;
atexit(&
delete);
//当程序终止执行时,执行delete函数
signal(SIGINT,&
sigdelete);
//接收到信号SIGINT则执行sigdelete函数
sunion.val=1;
safesemctl(semid,SN_EMPTY,SETVAL,sunion);
sunion.val=0;
safesemctl(semid,SN_FULL,SETVAL,sunion);
shmid=safeshmget(IPC_PRIVATE,SHMDATASIZE,IPC_CREAT|SHM_R|SHM_W);
shmdata=safeshmat(shmid,0,0);
safeshmctl(shmid,IPC_RMID,NULL);
//删除共享内存,当所有附加该共享内存的进程结束或断开与该共享内存的连接时才执行
*(int*)shmdata=semid;
buffer=shmdata+sizeof(int);
ServerisrunningwithSHMid**%d**\n"
while
(1)
Waitinguntilfull..."
fflush(stdout);
locksem(semid,SN_FULL);
done.\n"
Messagereceived:
%s.\n"
buffer);
unlocksem(semid,SN_EMPTY);
voidclient(intshmid)
intsemid;
semid=*(int*)shmdata;
Clientoperational:
shmidis%d,semidis%d\n"
shmid,semid);
charinput[3];
\n\nMenu\n1.sendamessage\n"
2.Exit\n"
fgets(input,sizeof(input),stdin);
switch(input[0])
case'
1'
:
clientwrite(shmid,semid,buffer);
break;
2'
exit(0);
voiddelete(void)
\nMasterexiting;
deletingsemaphore%d.\n"
deleteSemid);
if(semctl(deleteSemid,0,IPC_RMID,0)==-1)
Errorreleasingsemaphore.\n"
voidsigdelete(intsignum)
voidlocksem(intsemid,intsemnum)
structsembufsb;
sb.sem_num=semnum;
sb.sem_op=-1;
sb.sem_flg=SEM_UNDO;
safesemop(semid,&
sb,1);
voidunlocksem(intsemid,intsemnum)
sb.sem_op=1;
voidwaitzero(intsemid,intsemnum)
sb.sem_op=0;
sb.sem_flg=0;
voidclientwrite(intshmid,intsemid,char*buffer)
Waitinguntilempty..."
locksem(semid,SN_EMPTY);
EnterMessage:
"
fgets(buffer,BUFFERSIZE,stdin);
unlocksem(semid,SN_FULL);
intsafesemget(key_tkey,intnsems,intsemflg)
intretval;
if((retval=semget(key,nsems,semflg))==-1)
semgeterror:
strerror(errno));
exit(254);
returnretval;
intsafesemctl(intsemid,intsemnum,intcmd,unionsemunarg)
if((retval=semctl(semid,semnum,cmd,arg))==-1)
semctlerror:
intsafesemop(intsemid,structsembuf*sops,unsignednsops)
if((retval=semop(semid,sops,nsops))==-1)
semoperror:
intsafeshmget(key_tkey,intsize,intshmflg)
if((retval=shmget(key,size,shmflg))==-1)
shmgeterror:
void*safes