线程编程之浅尝辄止1

学习线程是一件很好玩的是,它不像进程那样复杂而且很好用。下面是我写的一段代码,附有一定的解释和说明,以及一些思考,看懂了我这段代码和注释,那么线程编程就入门了,合适新手研究。不对的地方请多多指教啊。

代码由A、B、C、D、E、EE六个线程,其功能有,主线程传参(结构体、整形、字符串)、子线程返回参数的两种方法、创建双层线程(父子孙,不建议这样做)以及他们之间的参数传递与计算等,好好研究吧。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

struct menber
{
    int a;
    char *s;
};

struct fo
{
	int a,b,c,d;
}foo={1,2,3,4};
void printfoo(const char *s,const struct fo *fp)
{
	printf("%s",s);
	printf("foo.a=%d\n",fp->a);
	printf("foo.b=%d\n",fp->b);
	printf("foo.c=%d\n",fp->c);
	printf("foo.d=%d\n",fp->d);
}
void *thr_D(void *arg)//子线程传给父线程一个结构体
{
	printfoo("我是线程D:\n",&foo);
	pthread_exit((void *)&foo);//这个地方的&引用一定不要丢,丢了,编译通过但运行出现段错误

}

void *thr_C(void *arg)//传递字符串
{
   char *name=(int *)arg; //-Wall编译时出现警告:从不兼容的指针尅想初始化
//   sleep(1);
   printf("我是线程C,ID = %u,得到的字符串name=%s\n",(unsigned int)pthread_self(),name);
   return (void *)0;
}
void *thr_B(void *arg)//传递整形
{
    int *m =(int *)arg; 
    printf("我是线程B,ID = %u,得到的整形m=%u\n",(unsigned int)pthread_self(),*m);
    return (void *)0;
}
void *thr_A(void *arg)//传递结构体
{
    struct menber *temp;
	temp=(struct menber *)arg;
    printf("我是线程A,ID = %u,我从进程得到strut:",(unsigned int)pthread_self());
    printf("menber->a = %d ; ",temp->a);
    printf("menber->s = %s  \n",temp->s);
    return (void *)0;
}
void *thr_EE(void *arg)//父子间互相通信
{
    int c;
    int *b=(void *)arg;
	printf("我是sun线程,");
	printf("请输入一个数:");
	scanf("%d",&c);//在%d后面不能加\n,不然执行到这句后,就不在执行了    
    c=c*(*b);		 
	printf("  经过计算*参数值得到c = %d\n",c);
    return (void *)c;
//这是线程与进程之间互相传至的程序,在线程中可以使用return 和
//pthread_exit,返回值到进程,效果是一样
}

void *thr_E(void *arg)//父子间互相通信
{
	pthread_t EE;
    int *aa=(int *)arg;
	int x =1;
	int *atr = &x;
	int *y;
	printf("我是zi线程,我得到了父线程的参数:%d\n",*aa);
	x=x+ (*aa);
	printf("  经过我的计算加1得出:%d\n",x);
	pthread_create(&EE, NULL, thr_EE,(void *)atr);
	pthread_join(EE,(void *)&y);
	printf("zi经过孙线程计算得到:%d\n",y);
	pthread_exit((void *)y);
}

int main(int argc,char *argv[])
{
    pthread_t A,B,C,D,E;
	int a,*count;
	int *atr=&a;

	
	int error;
	struct menber *b;
	struct fo *fp;
	int m =1;
    int *attr=&m;
	char *name ="My name is BHW!";
	b=(struct menber *)malloc( sizeof(struct menber) );
    b->a = 4;
    b->s = "我是hubbybob";
//3个思考题:
//1:3个join分别在creat函数下,会是什么结果?
//2:把3个join放到所有creat后面,回事什么结果?
//3:把3个join去掉,回事什么结果?
    error = pthread_create(&C, NULL, thr_C, (void *)name);
    error = pthread_create(&B, NULL, thr_B, (void *)attr);//如果传入的参数为多个,必须以结构体的形式传入
    error = pthread_create(&A, NULL, thr_A, (void *)b);
    //pthread_join(C, NULL);
  //  pthread_join(B, NULL);
//    pthread_join(A, NULL);
//答案:
//1:打印的结果是A-B-C的顺序,但是其线程的ID是一样的
//2:不管ABC的join的顺序如何,打印的结果只与creat的顺序,先执行最后一个,而且线程ID不一样,增大,为什么?
//3:去掉join后打印的顺序为CBA,打印顺序与creat的顺序有关,先执行最后一个,且线程ID不一样,增大,为什么?
//线程创建时不保证哪个线程先运行,其所有的现象调试都可用sleep,来调试,效果是很明显的,大家可以试一试
//并且可以通过sleep来调节他们的占空比
    sleep(1);
    printf("下面是由线程传给进程的参数:\n");
    error = pthread_create(&D, NULL, thr_D, NULL);
    pthread_join(D,(void *)&fp );
//这里的&引用符号不能少,少了后,编译通过,但运行发生段错误
//放生段错误,修改正确之后,再次编译会打印这样一条消息
//"You have new mail in /var/spool/mail/root"这是怎么回事呢?
	sleep(1);
	printfoo("我是D传回的:\n",fp);
    sleep(1);
	printf("下面在线程中创建一个线程,但是不推荐使用:\n");
//这是个很简单的多线程测试程序,在主线程中创建线程E ,在E 中创建EE ,
//其功能是实现 count=(x+1)*y,x有主线程输入,y有孙线程输入
//但是这是比较麻烦的,因为猪线程传值给E,E再传给EE,返回时EE返回给E,E再返回给主线程,
//有没有办法直接由EE返回值给主线程???
     printf("我是父线程,请输入主参数a:");
	 scanf("%d",&a); 
	 error = pthread_create(&E, NULL, thr_E,(void *)atr);
	 pthread_join(E,(void *)&count);
     printf("  经过zi与孙的计算得到count=%d\n",count);//-Wall选项编译时出现警告:%d为int,而参数为int *
	 sleep(2);
	return 0;
}

这段代码的结果:


另一段代码的研究:其结果就不附图了,感兴趣的话,可以用sleep函数来控制,亲自体验一下。

//这是一个很有意思的程序,其输出的顺序是可以改变的:
//1.当加上pthread_join()这个函数时,其顺序是先执行线程的内容,进程阻塞赛直至线程结束,但也与此函数的位置有关
//2.当不加pthread_join()这个函数时,其顺序可由sleep()函数控制
//3.当进程中的sleep去掉后则只能看到进程的内容被打印,是因为没有阻塞时,直接执行了return,结束了进程
//4.sleep可以控制线程与进程的占空比

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
void *thread(void *str)
{
    int i;
    for (i = 0; i < 6; ++i)
    {
       sleep(3);
        printf( "This in the thread : %d\n" , i );
    }
    return NULL;
}

int main()
{
    pthread_t pth;
    int i;
    int ret = pthread_create(&pth, NULL, thread, (void *)(i));
    
   // pthread_join(pth, NULL);
    printf("123\n");
    for (i = 0; i < 4; ++i)
    {
        sleep(1);
        printf( "This in the main : %d\n" , i );
    }
    pthread_join(pth, NULL);
    return 0;
}


 

猜你喜欢

转载自blog.csdn.net/hubbybob1/article/details/43342887