栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux下多线程编程

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux下多线程编程

进程和线程的区别

进程:进程是资源分配的最小单位,是程序执行时的实例,在程序运行时创建。

线程:线程是程序执行的最小单位,调度的基本单位,是进程的一个执行流。

并发和并行的区别

并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。其中两种并发关系分别是同步和互斥。

        同步:指进程间的关系是相互依赖。前一个进程的输出是后一个进程的输入。当前一个进程没有输出时,后一个进程必须等待。

        互斥:进程之间相互排斥地使用临界资源(一次仅允许一个进程使用地共享资源)。

并行:指在同一时刻,有多条指令在多个处理器上同时执行。

同步和异步的区别

同步:指进程间的关系是相互依赖。前一个进程的输出是后一个进程的输入。当前一个进程没有输出时,后一个进程必须等待。就是实时处理(如打电话)

异步:指进程间相互独立。执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。 就是分时处理(如收发短信)。

多线程编程 1.创建新线程 pthread_self函数:  获取线程ID
  • pthread_t pthread_self(void); 返回值:成功:0; 失败:无
  • 线程ID:pthread_t类型,在Linux下为无符号整数(%lu),当前Linux中可理解为:typedef  unsigned long int  pthread_t
pthread_create函数 : 创建一个新线程
  • int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
  • 返回值:成功:0; 失败:错误号 
  • 参数1:传出参数,保存系统为我们分配好的线程ID
  • 参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。
  • 参数3:函数指针,指向线程主函数(线程体),新创建的线程从start_routine函数的地址开始运行,该函数运行结束,则线程结束。
  • 参数4:线程主函数执行期间所使用的参数,有参数时输入参数的地址,如要传多个参数, 可以用结构封装。
  • //创建线程,返回线程序号和ID
    //Linux编译时加上 -lpthread
    //因为pthread并非Linux系统的默认库,而是POSIX线程库。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。
    //gcc -o more_pthread more_pthread.c -lpthread
    
    #include 
    #include 
    #include 
    #include 
    
    void *pth(void * arg);
    
    int main(int argc,char *argv[])
    {
    	int n,i;
    	pthread_t tid;
    
    	if(argc==2)
    	{
    		n=atoi(argv[1]);
    	
    	}
    
    	for(i=0;i atoi()代表的是ascii to integer,即“把字符串转换成有符号数字”,举例如下: 
  • char a="-10";
    char b="9";
    int c=atoi(a)+atoi(b);

    那么计算结果c=-10+9=-1。

  • int main(int argc,char * argv[]),表示的就是argc表示你使用这个程序时,输入的参数的个数,argv[]表示各个参数。

  • 默认argc为1,argv[0]为程序名称。如果输入一个参数,则argc为2,argv[0]为程序名称,argv[1]为输入的那个参数。以此可推出,多个输入参数的情况。

  • 运行结果

 

2. 单个线程退出 pthread_exit函数 : 将单个线程退出
  • void pthread_exit(void *retval); 参数:retval表示线程退出状态,通常传NULL
//退出线程

#include 
#include 
#include 
#include 

void *pth(void * arg);

int main(int argc,char *argv[])
{
	int n,i;
	pthread_t tid;

	if(argc==2)
	{
		n=atoi(argv[1]);
	
	}

	for(i=0;i 
运行结果 

 线程中,禁止使用exit函数,会导致进程内所有线程全部退出。

 3.等待线程结束 pthread_join函数:  阻塞等待线程退出,获取线程退出状态 
  • int pthread_join(pthread_t thread, void **retval)
  • thread: 线程标识符,即线程ID,标识唯一线程
  • retval: 用户定义的指针,用来存储被等待线程的返回值
//回收多个子线程

#include 
#include 
#include 
#include 

int var=10;
void *pth(void * arg);

int main(int argc,char *argv[])
{
	int i;
	pthread_t tid[5];
	int *ret[5];


	for(i=0;i<5;i++)
	{
		pthread_create(&tid[i], NULL, pth, (void *)i);
	}

	for(i=0;i<5;i++)
	{
		pthread_join(tid[i],(void**)&ret[i]);
		printf("=======%d  ret=%dn",i,(int)ret[i]);

	}


	printf("i am main,main_pthread_id = %lut var=%dn",pthread_self(),var);

	sleep(i);

	return 0;
}

void *pth(void *arg)
{
	int i;

	i=(int)arg;

	sleep(i);
	if(i==1)
	{
		var=20;
		printf("var=%dn",var);
		return (void*)var;
	}

	else if(i==3)
	{
		var=30;
		printf("i am %d pthread,id=%lu,var= %dn",i+1,pthread_self(),var);

		pthread_exit((void *)var);
	}
	else
	{
		 printf("i am %d pthread,id=%lu,var= %dn",i+1,pthread_self(),var);
		 pthread_exit((void *)var);
	}



	return NULL;

}

运行结果

 4.线程分离 pthread_detach函数:  实现线程分离
  • int pthread_detach(pthread_t thread); 成功:0;失败:错误号
  • 指定该状态,线程主动与主控线程断开关系。线程结束后(不会产生僵尸线程),其退出状态不由其他线程获取,而直接自己自动释放(自己清理掉PCB的残留资源)。网络、多线程服务器常用。
#include 
#include 
#include 
#include 
#include 

void *pth(void * arg);

int main(int argc,char *argv[])
{
	int err;
	pthread_t tid;
	void *tret;

#if 1
	pthread_attr_t attr;  //通过线程属性来设置游离态(分离态)
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	pthread_create(&tid,&attr,pth,NULL);

#else
	pthread_create(&tid,NULL,pth,NULL);
	pthread_detach(tid);    //让线程分离  ----自动退出,无系统残留资源

#endif

	while(1)
	{
		err=pthread_join(tid,&tret);
		printf("thread exit code=%dn",(int)tret);
		printf("========err=%dn",err);

		if(err!=0)
		{
			fprintf(stderr,"thread join err:%snn",strerror(err));
		}

		else
		{
			 fprintf(stderr,"thread join err:%snn",(int)tret);
		}

		sleep(2);
	}

	return 0;
}

void *pth(void *arg)
{
	int n=3;

	while(n--)
	{
		printf("thread count %dn",n);
		sleep(1);
	}

	return (void *)1;
}
运行结果

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/888089.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号