在我们学习进程间的通信的时候,我们需要知道的是,什么是进程,什么是线程。
狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
线程间的通信可以在用户空间中实现
列如:
#include"stdio.h"
#include"sys/types.h"
#include"stdlib.h"
int main()
{
pid_t pid;
pid=fork();
int process_inter=0;
if(pid==0)//child processes
{
while(process_inter==0);
int i=0;
for(;i<5;i++)
{
printf("\nI am child process ! %d\n",i);
}
usleep(100);
}
else if(pid>0)//child processes
{
int i=0;
for(;i<5;i++)
{
printf("\nI am parent process ! %d\n",i);
}
process_inter=1;
usleep(100);
}
else
{
printf("\nprocess request faile!\n");
}
while(1);
return 0;
}
我们在main函数中加入了一个变量process_inter ,这是一个信号量,当父进程运行完了以后将信号量赋值为1,这样就可以运行子进程,但是结果却不是我们想的一样
运行结果如下
这是为什么呢?
因为进程是一个封闭,正如之前的概念图,进程是不能在用户空间进行通信的,只能通过Linux内核作为媒介进行数据的交换。
所以线程可以在用户空间进行通信。
#include<unistd.h>
#include<stdio.h>
#include <stdlib.h>
#include <pthread.h>
int state=0;
void *func1(void *var)
{
int i=0;
for(;i<5;i++)
{
while(state!=2);
printf("\nI am thread 1 ! %d\n",i);
usleep(200);
}
}
void *func2(void *var)
{
int i=0;
for(;i<5;i++)
{
printf("\nI am thread 2 ! %d\n",i);
usleep(200);
state++;
}
}
int main(void)
{
pthread_t tid,tid2;
int ret;
int i=0;
if(pthread_create(&tid,NULL,(void*)func1,NULL)!=0){return -1;}
if(pthread_create(&tid2,NULL,(void*)func2,NULL)!=0){return -1;}
pthread_join(tid,NULL);
pthread_join(tid2,NULL);
while(1);
return 0;
}
运行结果如下:当线程1把状态置为2的时候,线程1才启动,所以线程间在用户空间是可以通信的
多线程,多进程创建的一般步骤:
1. 创建线程号ID,pthread_t ,创建进程号ID pid_t
2. pthread_create(&tid,NULL,(void*)func1,NULL) //创建线程,将线程号注册进函数,同时将线程服务函数注册,至于第二,第四个参数可传,可不传
pid=fork(); //通过fork()函数创建 通过pid判断是父进程还是子进程,0为子进程,大于0为父进程
//pthread_create创建线程后需要销毁,不销毁会导致内存泄露。
//1.使用pthread_join销毁。因要等待线程执行完所以会导致主线程阻塞。
//2.使用pthread_detach(pthread_self()),在线程执行完后会自动销毁。注意在线程执行函数要能退出。
//3.两者同时使用时会导致pthread_join不再阻塞