Linux线程

1:从进程引入线程

用多进程(父子进程)分别去执行两个任务(读文件I/O),哈哈这个例子用多进程在于,各自的程序都是阻塞等待一个任务;

代码如下:

#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>



int main(void)

{
	int ret = -1;
	int fd = -1;
	char buf[100] ={0};
	char buf1[100] ={0};
	pid_t fpid = -1;
	
	printf("this is parent process\n");
	
	fd = open("/dev/input/mouse0",O_RDONLY);
	if(-1==fd)
	{
		perror("open");
		return -1;
	}
	
	fpid = fork();
	if (-1==fpid)
	{
		perror("fork");
		return -1;
		
	}
	if (0==fpid)
	{
		printf("this is child process\n");
		while(1)
		{
			memset(buf,0,sizeof(buf));
			ret=read(fd,buf,7);
			if(-1==ret)
			{
				perror("read");
				return -1;
			}
			printf("子进程读鼠标【%s】\n",buf);
			
		}
		
	}
	else if(fpid>0)
	{
		
		printf("this is prantent process\n");
		while(1)
		{
			memset(buf1,0,sizeof(buf1));
			ret=read(0,buf1,7);
			if(-1==ret)
			{
				perror("read");
				return -1;
			}
			printf("父进程读键盘【%s】\n",buf1);
			
		}
	}	
		
		else
		
	{
		perror("fork");
		return -1;
		
	}
			
	
	
	
	
	
	return 0;
}

 多进程的好处:

  • 操作系统可以处理多个任务,也就是其实可以在多个进程之间跳来跳去;
  • cpu是分时复用的;

坏处:

  • 进程调度开销大;
  • 进程间通信巨麻烦;

所以引入线程:

  • 节省进程开销;
  • 多核cpu越来越是为了满足多线程的功能的;
  • 可以实现多任务;

线程详解

相关概念:

  • 一种轻量级的进程;
  • 线程是参与内核调度的最小单元;线程更加接近于执行体的概念;
  • 一个进程当中有多个线程
  • 同一个进程中多个线程可以共享数据,但拥有各自的栈空间,独立的执行序列;

线程技术的优势:

  • 可以像进程一样被OS调度;
  • 进程之间通信效率很容易也很高效;(就好像同一个进程中,不同函数直接的通信)
  • 很合适多核心CPU(对称多处理器架构SMP)架构下效率最大化;多线程可以并发在多核当中执行;多进程却不能保证这种并发执行;

缺点:不利于资源的管理和保护;不利于跨机器迁移(???);

线程常用函数

新手教程:新手教程(线程创建,线程属性,线程取消)

一个线程通过一个函数调用产生,产生的thread什么时候死,什么时候(进程被结束的时候死,自己执行完毕,被另一个线程杀死(立刻,还是缓刑))

线程创建与回收


(1)pthread_create        主线程用来创造子线程的

线程属性:__detachstate(线程间是否同步),__schedpolicy(调度策略),__schedparam(运行优先级)~~~~~~。。。。。

线程属性还可以通过函数:为了设置这些属性,POSIX定义了一系列属性设置函数,包括pthread_attr_init()、pthread_attr_destroy()和与各个属性相关的pthread_attr_get---/pthread_attr_set---函数。

join 和detch;
(2)pthread_join            主线程用来等待(阻塞)回收子线程
(3)pthread_detach        主线程用来分离子线程,分离后主线程不必再去回收子线程

 

大概理解就是:子线程死亡还剩下线程的栈资源,第一种是等其他线程调用join处理,第二种是设置线程属性让他自己为自己收尸;


线程取消解释


(1)pthread_cancel        一般都是主线程调用该函数去取消(让它赶紧死)子线程
(2)pthread_setcancelstate    子线程设置自己是否允许被取消
(3)pthread_setcanceltype

 

cancle 函数的相关实验:

1:如果子线程是默认的,可以结束,结束执行工作时立即执行的话,在父线程发结束信号,子线程会立刻结束;(有个问题,这时还需要处理栈资源吗?估计要;)

2:愁死了,一发取消信号线程就结束,说好要取消点的呢?完全不懂;

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


void* t_func(void *arg);




int main(void)

{
	pthread_t tpid = -1;
	int ret = -1;
	
	ret = pthread_create(&tpid,NULL,t_func,NULL);
	if (0!= ret)
	{
		printf("error pthread_create\n");
		return -1;
		
	}
	
	sleep(3);
	printf("wait for child thread run \n");
	
	pthread_cancel(tpid);



	return 0;
}


void* t_func(void *arg)
{
	int i = 1;
	int j = 0;
	
	printf("this child thread\n");
	
	for(j=0;j<100;j++)
	{
	
		sleep(1);
		
		printf("i = %d second\n",i);
		
		i++;
	}
	
	return NULL;
}


线程函数退出相关


(1)pthread_exit与return退出
(2)pthread_cleanup_push
(3)pthread_cleanup_pop


获取线程id


(1)pthread_self

 

备注:

p是指:posix 标准,linux是满足posix标准的;

线程函数能用return ,不能用exit(这个是进程结束返回)

注意点:线程函数出现错误不能够用perror打印?

写一个有子线程的进程:

#include<stdio.h>
#include <pthread.h>
#include<string.h>
#include <sys/types.h>
#include <unistd.h>



void* t_func(void *arg);
void printf_m(char *s)
{
	pid_t pid = -1;
	pthread_t tid = -1;
	pid = getpid();
	tid = pthread_self();
	printf("%s,process id = %d ,thread id = %ld\n",s,pid,tid);
	return;
	
}




int main(void)
{

	int ret = -1;
	pthread_t tid = -1;
	
	ret = pthread_create(&tid,NULL,t_func,NULL);   //线程创建
	if(0!=ret)
	{
		printf("error pthread_create\n");
		return -1;
	}
	
	printf_m("main thread\n");
	
	
	//sleep(10);                            //不加这个进程会在子线程没执行前被结束掉;
	pthread_join(tid,NULL);					//或者加这个线程回收函数;


	return 0;
}


void* t_func(void * arg)
{
	printf_m("new thread\n");
	
	return 0;
}

main thread
,process id = 4893 ,thread id = 140712045283136
new thread
,process id = 4893 ,thread id = 140712036767488
 反思总结:NULL的含义,字符串要再看;restrict这个关键字;

线程同步   (信号量方法同步)semaphore这个信号的教程

主要是用了sem 这个函数族;

下面的程序主要是子线程得等父线程输入字符,然后才可以读取;我理解就是在一个线程设置一个断点,然后得等另一个线程发布个信号才可以执行;

 

//任务:用户从终端输入任意字符然后统计个数显示,输入end则结束


#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include <semaphore.h>

void* t_func(void*arg);
char  buf[200] = {0};

sem_t sem;

int main(void)

{
	
	int ret = -1;
	while(1)
	{
	printf("please input some characters,if input end this process will end\n");
	
	scanf("%s",buf);       
	if (0!=strncmp(buf,"end",3))
	{
	sem_post(&sem);
	
	}
	else
	{
		return 0;
	}
	
	}
	
	return 0;
}


void* t_func(void*arg)
{

	while(1)
	{
	sem_wait(&sem);
	printf("%s\n",buf);
	memset(buf,0,sizeof(buf));
	}
}












 线程同步之互斥锁教程

 安装线程相关的man手册

pthread_mutex_init,      pthread_mutex_lock,     pthread_mutex_trylock,
       pthread_mutex_unlock, pthread_mutex_destroy

条件变量

pthread_cond_init,      pthread_cond_destroy,      pthread_cond_signal,
       pthread_cond_broadcast,  pthread_cond_wait,  pthread_cond_timedwait 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值