C语言中的线程知识点

1.守护线程的创建

定义:周期性的执行某项任务或等待某个事件发生的进程,不依赖shell终端,生存周期较长。(从开机开始到关机结束)。
进程组与会话期的描述

守护进程的创建步骤:

  1. 创建一个子进程,让父进程退出。
    fork()
  2. 在子进程中,创建新的会话期
    脱离当前会话期。
    setsid();创建新会话期的函数。
  3. 改变子进程的工作目录
    chdir(“/”);改为根目录,因为根目录永远不会被删除。
  4. 取消文件权限掩码
    文件权限
    将文件的某一个权限掩掉,取消其他用户中的写操作
    恢复文件原来具有的权限。
    umask(0);与操作
    文件111 110 111 777–>775
    000 000 010
  5. 关闭所有文件描述符
    系统最多一下打开1024个,stdin、stdout、stdout默认打开,剩下1021个。
    getdtablesize();//获取该系统可以一下最多打开多少个文件
    执行结果
    守护进程创建案例代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>

int main()
{
	int i;
	//fork创建子进程
	pid_t pid=-1;
	pid=fork();
	if(-1==pid)
	{
		return -1;
	}
	if(pid>0)
	{
		exit(0);
	}
	printf("1:fork OK!\r\n");
	//2set new section
	setsid();
	printf("2:create new section OK!pid=%d\r\n",getpid());
	//3 chdir /
	chdir("/");
	//4.取消文件掩码
	umask(0);
	//5.close all file
	int num=getdtablesize();
	//获取该系统可以最多一下打开多少个文件
	for(i=0;i<num;i++)
	{
		close(i);
	}
	sleep(20);

	return 0;
}

![守护进程创建成功](https://img-blog.csdnimg.cn/c09f57373a984acf87d4e44424af9cc4.png
关于目录操作的函数:
opendir();chdir();readdir();

2.线程相关

定义:线程是轻量级的进程,用task_struct表示,他没有自己独立的内存空间,它与其他线程共享创建它的进程的地址空间。
多个线程在一个地址空间内

3.线程创建

可以使用第三方线程库提供的API(接口)
线程创建函数
pthread_create测试案例:

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

void *ThreadFunc(void *arg)
{
	printf("test by all@1201---------------\r\n");
}
int main()
{
	printf("hello world\r\n");
	pthread_t tID=-1;
	if(0!=pthread_create(&tID,NULL,ThreadFunc,NULL))
	{
		printf("create pthread error\r\n");
		return -1;
	}
//	char *pStr=NULL;
	pthread_join(tID,NULL);
	printf("hello 22101------------\r\n");
	return 0;
}

创建进程函数测试案例结果
在这里插入图片描述

阻塞等待线程的函数

线程退出函数
退出当前子线程
线程退出函数

取消线程函数
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。有时会终止线程的运行,有时不会。看系统的运行定

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

void *ThreadFunc(void *arg)
{
	printf("test by all@1201---------------\r\n");
}
int main()
{
	printf("hello world\r\n");
	pthread_t tID=-1;
	if(0!=pthread_create(&tID,NULL,ThreadFunc,NULL))
	{
		printf("create pthread error\r\n");
		return -1;
	}
	//参数:线程号
	//成功返回0,失败返回非零数
	if(0!=pthread_cancel(tID))
	{
		printf("线程取消失败\r\n");
	}
	printf("hello 22101------------\r\n");
	return 0;
}

取消线程测试
unubtu的组成=Linux内核+各种工具+桌面+各种库+已经写好的各种应用程序

4.多线程的通信 同步 互斥

在一个进程中可以创建多个线程,那么多个线程间会存在数据通信问题,会存在两个线程相互配合完成一件事情(线程同步),会存在两个线程对公共资源的竞态访问问题(互斥问题)。
案例同时创建多个线程:

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

void *ThreadFunc1(void *arg)
{
	printf("test by fun1---------------\r\n");
}
void *ThreadFunc2(void *arg)
{
	printf("test by fun2----------------\r\n");
}
int main()
{
	printf("hello world\r\n");
	pthread_t tID1=-1;
	pthread_t tID2=-1;
	if(0!=pthread_create(&tID1,NULL,ThreadFunc1,NULL))
	{
		printf("create pthread error\r\n");
		return -1;
	}
	if(0!=pthread_create(&tID2,NULL,ThreadFunc2,NULL))
	{
		printf("create pthread2 error!\r\n");
		return -1;
	}
//	char *pStr=NULL;
	pthread_join(tID1,NULL);
	pthread_join(tID2,NULL);
	printf("hello 22101------------\r\n");
	return 0;
}

查看系统可以支持的最大线程数和最大进程数指令。
①系统支持的最大线程数
②系统支持的最大进程数
最大线程进程指令

4.1多线程的数据通信

使用全局变量实现

4.2多线程的同步

用无名信号量 sem_t sem;
同步:两个线程相互配合按照一定的顺序完成一件事情。
pthread1–>hello 1s sem_t sema;–>P/V操作函数控制sema和semb
pthread2–>world 1s sem_t semb;

P操作:sem_wait(&sema);
含义:sem_wait会检测信号量sema的值是否大于0,若大于0,将sema减1,同时函数返回。若等于0,则阻塞当前线程

V操作:sem_post(&sema);----->非阻塞函数
含义:sem_post只会给检测的信号量sema+1;

实现打印:hello world hello world…
案例:

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t sema;
sem_t semb;
void *ThreadFunc1(void *arg)
{
	int i=10;
	while(i--)
	{
		sem_wait(&sema);
		printf("hello-----\r\n");
		sleep(1);
		sem_post(&semb);//将semb置1
	}
}
void *ThreadFunc2(void *arg)
{
	int i=10;
	while(i--)
	{
		sem_wait(&semb);
		printf("world-----------------\r\n");
		sleep(1);
		sem_post(&sema);//'将sema置为1
	}
}
int main()
{
	printf("hello world\r\n");
	pthread_t tID1=-1;
	pthread_t tID2=-1;
	if(-1==sem_init(&sema,0,1)||-1==sem_init(&semb,0,0))
	{
		return -1;
	}
	if(0!=pthread_create(&tID1,NULL,ThreadFunc1,NULL))
	{
		printf("create pthread error\r\n");
		return -1;
	}
	if(0!=pthread_create(&tID2,NULL,ThreadFunc2,NULL))
	{
		printf("create pthread2 error!\r\n");
		return -1;
	}
//	char *pStr=NULL;
	pthread_join(tID1,NULL);
	pthread_join(tID2,NULL);
	printf("hello 22101------------\r\n");
	return 0;
}

在这里插入图片描述
sem函数

4.3多线程的互斥

互斥:多个线程可能会使用同一段公共资源,若是同时访问这一段公共资源就会造成多个线程对公共资源竞争,从而造成访问结果混乱。
如何解决?可以使用互斥锁
1.多个线程是否受用同一个线程执行函数
2.两个线程给线程执行函数传入不同的参数,最后结果是否发生混乱。
3.使用互斥锁解决两线程的互斥访问公共资源
pthread_mutex_t mutex;//定义了一个全局的线程互斥锁
在这里插入图片描述

pthread_mutex_init(&mutex,NULL(互斥锁的默认属性));

pthread_mutex_unlock(&mutex);

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值