需求介绍
实现两个进程间的通信,一个进程从键盘输入字符串,发送给另一个进程。接收进程将该字符串逆序,并输出相应的结果。
简单介绍
-
fork()用于创建新进程
-
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 )
- addr指定文件应被映射到进程空间的起始地址,一般被指定一个空指针,此时选择起始地址的任务留给内核来完成。
- len是映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起。
- prot 参数指定共享内存的访问权限。可取如下几个值的或:PROT_READ(可读) , PROT_WRITE (可写), PROT_EXEC (可执行), PROT_NONE(不可访问)
- flags由以下几个常值指定:MAP_SHARED , MAP_PRIVATE , MAP_FIXED,其中,MAP_SHARED , MAP_PRIVATE必选其一,而MAP_FIXED则不推荐使用。
- fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,此时须指定flags参数中的MAP_ANON,表明进行的是匿名映射(不涉及具体的文件名,避免了文件的创建及打开,很显然只能用于具有亲缘关系的进程间通信)。
- offset参数一般设为0,表示从文件头开始映射。函数的返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址为该值的有效地址。
-
int munmap( void * addr, size_t len )
该调用在进程地址空间中解除一个映射关系,addr是调用mmap()时返回的地址,len是映射区的大小。当映射关系解除后,对原来映射地址的访问将导致段错误发生。
代码
#include <bits/stdc++.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>
#include <string>
using namespace std;
// 消息
char* msg;
// 定义两个信号量
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);
msg=(char*)mmap(NULL,sizeof(char), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1,0);
sem_init(m1,1,1); //对信号量进行初始化
sem_init(m2,1,0);
if(fork()){ //fork用于创建进程
//以下基本就是操作系统进程通信的信号量一些简单算法了,不多说了
for(int i=0;i<10;i++){
sem_wait(m2);
cout<<"请发送数据:";
cin>>msg;
sem_post(m1);
}
}else{
for(int i=0;i<10;i++){
sem_wait(m1);
string str = msg;
reverse(str.begin(),str.end());
cout<<"接受到的数据逆序:"<<str<<endl;
sem_post(m2);
}
return 0;
}
sem_destroy(m1);
sem_destroy(m2);
munmap(m1,sizeof(sem_t));
munmap(m2,sizeof(sem_t));
return 0;
}
运行
-
创建一个thread_msg2.cpp文件,将代码写入
-
进行编译
g++ -g thread_msg2.cpp -o thread_msg2 -pthread
可能需要下载安装一下:yum install -y gcc-c++
-
运行
./thread_msg2
-
结果