linux 多進程的同步:linux多進程我實現同步操作,操作單個信號量已經不能實現,對多進程的通信可以採取信號集的方式,一個信號集包含了多個信號量。
首先通過semget()創建信號量。例如:semid = semget(SEMKEY,2,0600|IFLAGS;
然後對信號集中各個信號量賦初值:
semctl(semid,0,SETVAL,0);
semctl(semid,1,SETVAL,1);
也可以通過 set_sem_value(semid,0,1),對信號集爲semid重的第一個信號量賦初始值爲1
void set_sem_value(int semid,int num ,int val)
{
union semun semun_info;
semun_info.val=val;
semctl(semid,0,SETVAL,semun_info);
}
然後就是類似於PV原語的操作。
注意一下下面的這個機構體:
struct sembuf p1 = {0,-1,0},p2 = {1,-1,0},
v1 = {0,1,0},v2 = {1,1,0};
然後利用 int semop(int semid, struct sembuf *sops, unsigned nsops); 進行pv操作!。下面是具體的代碼:
/**************************************produce.c*******************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include<errno.h>
#define SHMKEY (key_t) 0x100
#define SEMKEY (key_t) 0x200
#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define ERR ((struct databuf *) -1)
struct databuf{
int d_buf[10];
};
static int shmid,semid;
pr_error(char *mess)
{
perror(mess);
exit(1);
}
getseg(struct databuf* *pdata)
{
/*取得共享內存的key,如果還沒建立的話,就建立(IPC_CREAT)*/
if((shmid =shmget(SHMKEY,sizeof(struct databuf),0600|IFLAGS)) < 0)
{
if( errno == EEXIST)
{
shmid=shmget(SHMKEY,sizeof(struct databuf),0600|IPC_CREAT);
if(shmid <0)
pr_error("shmget");
}
else
pr_error("shmget");
}
/*取得共享內存的指針,使用共享內存時可以和malloc分配的內存一樣*/
if((*pdata = (struct databuf *)(shmat(shmid,0,0))) == ERR)
pr_error("shmat");
}
int getsem()
{ /*建立信號量(且稱爲A和B)*/
if((semid = semget(SEMKEY,2,0600|IFLAGS)) < 0)
{
if(errno == EEXIST)
{
semid=semget(SEMKEY,2,0600|IPC_CREAT);
if( semid <0)
pr_error("semget");
else
/*加上這一句,如果已存在,不再初始化信號量*/
return semid;
}
else
pr_error("semget");
}
/*設置信號量A初值爲0*/
if(semctl(semid,0,SETVAL,0) < 0)
pr_error("semctl");
/*設置信號量B初值爲1*/
if(semctl(semid,1,SETVAL,1) < 0)
pr_error("semctl");
return(semid);
}
void remove_s()
{
/*刪除共享內存*/
if(shmctl(shmid,IPC_RMID,NULL) < 0)
pr_error("shmctl");
/*刪除信號量*/
if(semctl(semid,IPC_RMID,NULL) < 0)
pr_error("semctl");
}
main()
{
int semid;
struct databuf *buf;
semid = getsem();
getseg(&buf);
writer(semid,buf);
remove_s();
exit(0);
}
struct sembuf p1 = {0,-1,0},p2 = {1,-1,0},
v1 = {0,1,0},v2 = {1,1,0};
writer(int semid,struct databuf *buf)
{
int i,j;
for(i = 0;i < 10;i++){
/*P(B) B=0;準備寫緩衝區*/
printf("next loop\n");
semop(semid,&p2,1);
/*寫共享內存*/
for(j = 0;j < 10;j++){
buf -> d_buf[j] = 10 * i + j;
printf("buf->d_buf[%d]=%d\n",j,buf -> d_buf[j] );
}
sleep(5);
/*V(A) A==1,喚醒消費者進程,讀緩衝區*/
semop(semid,&v1,1);
}
return;
}
/****************************consumer.c***************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include<errno.h>
#define SHMKEY (key_t) 0x100
#define SEMKEY (key_t) 0x200
#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define ERR ((struct databuf *) -1)
struct databuf{
int d_buf[10];
};
static int shmid,semid;
pr_error(char *mess)
{
perror(mess);
exit(1);
}
getseg(struct databuf* *pdata)
{
/*取得共享內存的key,如果還沒建立的話,就建立(IPC_CREAT)*/
if((shmid =shmget(SHMKEY,sizeof(struct databuf),0600|IFLAGS)) < 0)
{
if( errno == EEXIST)
{
shmid=shmget(SHMKEY,sizeof(struct databuf),0600|IPC_CREAT);
if(shmid <0)
pr_error("shmget");
}
else
pr_error("shmget");
}
/*取得共享內存的指針,使用共享內存時可以和malloc分配的內存一樣*/
if((*pdata = (struct databuf *)(shmat(shmid,0,0))) == ERR)
pr_error("shmat");
}
int getsem()
{ /*建立信號量(且稱爲A和B)*/
if((semid = semget(SEMKEY,2,0600|IFLAGS)) < 0)
{
if(errno == EEXIST)
{
semid=semget(SEMKEY,2,0600|IPC_CREAT);
if( semid <0)
pr_error("semget");
else
/*加上這一句,如果已存在,不再初始化信號量*/
return semid;
}
else
pr_error("semget");
}
/*設置信號量A初值爲0*/
if(semctl(semid,0,SETVAL,0) < 0)
pr_error("semctl");
/*設置信號量B初值爲1*/
if(semctl(semid,1,SETVAL,1) < 0)
pr_error("semctl");
return(semid);
}
main()
{
int semid;
struct databuf *buf;
semid = getsem();
getseg(&buf);
reader(semid,buf);
exit(0);
}
struct sembuf p1 = {0,-1,0},p2 = {1,-1,0},
v1 = {0,1,0},v2 = {1,1,0};
reader(int semid, struct databuf *buf)
{
int i,j;
for(i = 0;i <10;i++){
/*P(A) A==-1,如果沒數據的話,blocking,有的話,讀*/
printf("next loop\n");
semop(semid,&p1,1);
for(j = 0;j < 10;j++){
printf(" %d ",buf -> d_buf[j]);
}
printf("\n");
semop(semid,&v2,1);
/*V(B) B++,喚醒寫進程*/
}
return;
}