使用fork创建进程,实现两个进程之间的通信,一个进程把一个变量的值加5,另一个进程输出该变量的值。
sem_t:C语言中,信号量的数据类型为结构sem_t,它本质上是一个长整型的数。
函数sem_init (sem_t *sem, int pshared, unsigned int value) 这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。如果 pshared的值是0,就表示它是当前进程的局部信号量;否则,其它进程就能够共享这个信号量。只对不让进程共享的信号量感兴趣。(这个参数受版本影响), Linux线程一般不支持进程间共享信号量,pshared传递一个非零将会使函数返回ENOSYS错误。
函数sem_post( sem_t *sem )用来增加信号量的值当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不再阻塞,选择机制同样是由线程的调度策略决定的。
函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。
函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。
函数sem_destroy(sem_t *sem)用来释放信号量sem。
mmap():mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。
mmap()系统调用形式如下:
void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )
参数fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,此时须指定flags参数中的MAP_ANON,表明进行的是匿名映射(不涉及具体的文件名,避免了文件的创建及打开,很显然只能用于具有亲缘关系的进程间通信)。len是映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起。prot 参数指定共享内存的访问权限。可取如下几个值的或:PROT_READ(可读) , PROT_WRITE (可写), PROT_EXEC (可执行), PROT_NONE(不可访问)。flags由以下几个常值指定:MAP_SHARED , MAP_PRIVATE , MAP_FIXED,其中,MAP_SHARED , MAP_PRIVATE必选其一,而MAP_FIXED则不推荐使用。offset参数一般设为0,表示从文件头开始映射。参数addr指定文件应被映射到进程空间的起始地址,一般被指定一个空指针,此时选择起始地址的任务留给内核来完成。函数的返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址为该值的有效地址。
int munmap( void * addr, size_t len )
该调用在进程地址空间中解除一个映射关系,addr是调用mmap()时返回的地址,len是映射区的大小。当映射关系解除后,对原来映射地址的访问将导致段错误发生。
#include <bits/stdc++.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #include <sys/mman.h> using namespace std; int *cnt; sem_t *m1=NULL,*m2=NULL; int main() { m1=(sem_t*)mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0); m2=(sem_t*)mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0); cnt=(int*)mmap(NULL,sizeof(int), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1,0); sem_init(m1,1,1); sem_init(m2,1,0); *cnt=5; if(fork()){ for(int i=0;i<10;i++){ sem_wait(m2); cout<<"cnt="<<*cnt<<endl; sem_post(m1); } }else{ for(int i=0;i<10;i++){ sem_wait(m1); cout<<"add 5"<<endl; *cnt+=5; sem_post(m2); } return 0; } sem_destroy(m1); sem_destroy(m2); munmap(m1,sizeof(sem_t)); munmap(m2,sizeof(sem_t)); munmap(cnt,sizeof(int)); return 0; }