主要演示:进程和线程对与资源的关系
进程的所有资源被个线程所共享,包括可执行代码段、全局变量、对空间、栈空间、文件描述符等
1、代码分析多进程线程对进程全局变量的共享
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int a=1;
int flag=0;//一个标记,当线程fn1更改进程的值时线程fn2输出更新的数据
void *fn1();
void *fn2();
int main()
{
int err;
printf("进程的初始值为--1--\n");
pthread_t tid1,tid2;
err=pthread_create(&tid1,NULL,fn1,NULL);
if(err!=0)
{
printf("fail to create fn1\n");
exit(1);
}
err=pthread_create(&tid2,NULL,fn2,NULL);
if(err!=0)
{
printf("fail to create fn2\n");
exit(1);
}
while(1);
return 0;
}
void *fn1()
{
int b;
while(1)
{
sleep(1);
printf("请输入要更改线程的值:");
scanf("%d",&b);
flag=1;
a=b;
}
}
void *fn2()
{
while(1)
{
if(flag==1)
{
printf("线程fn1更新后的数据为:");
printf("a=%d\n",a);
flag=0;
}
}
}
通过结果可以看出:线程与进程共享全局变量,一个线程对与全局变量的影响可以影响到其他进程
2、代码分析多进程线程对进程局变量的共享
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *show()
{
printf("%d\n",a);
}
int main()
{
int a=1;
pthread_t tid;
int err;
err=pthread_create(&tid,NULL,show,NULL);
if(err!=0)
{
printf("fail to create\n");
exit(1);
}
return 0;
}
通过上边的云词那个结果可以看出,线程对与局部变量是没有共享的,这样说是做的,接下来将演示正确的方法
3、进程的所有资源被个线程所共享,包括可执行代码段、全局变量、对空间、栈空间、文件描述符
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//参数结构,将一个堆的指针和一个进程的局部变量传递给新线程
typedef struct arg_struct
{
int *heap; //堆数据的指针
int *stack; //栈数据的指针
}ARG;
FILE *fp=NULL; // 文件对象指针,其中包括文件描述符
void *thfn(void *arg)
{
ARG *p;
p=(ARG*)arg;
(*p->heap)++;
(*p->stack)++;
fprintf(fp,"new thread heap:%d stack:%d\n",*(p->heap),*(p->stack));
printf("the new thread done \n");
return NULL;
}
int main()
{
pthread_t tid,tid2;
ARG arg;
int *heap;
int stack;
int err;
heap=(int*)malloc(sizeof(int));
if(heap==NULL)
{
perror("fail to malloc");
exit(1);
}
*heap=2;
stack=3;
/*设置arg参数结构,栈数据结构必须以指针的形式传递给新线程
全局变量可以在线程函数中直接饮用
堆数据的操作方式主要看其首地址的指针存储方式*/
arg.heap=heap;
arg.stack=&stack;
if(((fp=fopen("guo","wb"))==NULL))
{
perror("fail to open");
exit(1);
}
err=pthread_create(&tid,NULL,thfn,(void*)&arg);
if(err!=0)
{
printf("cannot create thread %s\n",strerror(err));
exit(1);
}
sleep(10);
(*heap)++;
stack++;
fprintf(fp,"main thread:heap:%d satck:%d\n",*(arg.heap),*(arg.stack));
printf("the main thrad done\n");
fclose(fp);
free(heap);
return 0;
}
从结果看出线程是共享进程的资源的
总结:由于文件中有新线程输出的内容,所以新线程和进程共用文件描述符、文件对象和数据段;由于对数据和栈数据在thfn函数中的自增可以影响到主线程,所以新线程和进程公用堆和栈。因此,进程中的地址空间对与他的任意一个线程都是开放的。