嵌入式开发学习———Linux环境下IO进程线程学习(五)

发布于:2025-08-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

进程

僵尸进程

僵尸进程是子进程终止后,父进程未调用wait()waitpid()回收其退出状态,导致进程描述符仍留在系统中。此时子进程称为“僵尸进程”。

#include <unistd.h>
#include <stdlib.h>
int main() {
    pid_t pid = fork();
    if (pid == 0) exit(0);  // 子进程立即退出
    else sleep(60);         // 父进程不回收子进程
    return 0;
}
孤儿进程

孤儿进程是父进程先于子进程终止,子进程被init进程(PID=1)接管。孤儿进程不会对系统造成危害。

#include <unistd.h>
#include <stdlib.h>
int main() {
    pid_t pid = fork();
    if (pid == 0) sleep(60);  // 子进程存活
    else exit(0);             // 父进程先退出
    return 0;
}
守护进程

守护进程是在后台长期运行的独立进程,通常脱离终端控制。通过fork()后让父进程退出,子进程调用setsid()创建新会话。

#include <unistd.h>
#include <stdlib.h>
int main() {
    pid_t pid = fork();
    if (pid > 0) exit(0);    // 父进程退出
    setsid();                // 子进程创建新会话
    while (1) sleep(1);      // 守护任务
    return 0;
}

线程

线程概念

线程是程序执行的最小单位,属于同一进程的多个线程共享内存空间,但拥有独立的栈和寄存器。相比进程,线程切换开销更小,适合并发任务。

C语言线程核心函数(POSIX标准)

pthread_create
创建新线程,执行指定函数。

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

read_join
阻塞当前线程,等待目标线程终止并回收资源。

int pthread_join(pthread_t thread, void **retval);

pthread_exit
终止调用线程,返回结果可通过pthread_join获取。

void pthread_exit(void *retval);

作业:

1.使用创建两个线程,一个线程拷贝文件的前一部分,另一个线程拷贝文件的后一部分

#include <myhead.h>

int flatg=0;

void *PrevCopy(void *arg)
{
	FILE *fp1=NULL,*fp2=NULL;
	fp1=fopen("./myfile1","r");
	if(fp1==NULL)
	{
		printf("fp1=fopen error\n");
		return NULL;
	}
	fp2=fopen("./myfile2","a");
	if(fp2==NULL)
	{
		printf("fp2=fopen error\n");
		return NULL;
	}

	int size=*(int*)arg;
	for(int i=0;i<size/2;i++)
	{
		char ch;
		ch=fgetc(fp1);
		fputc(ch,fp2);
	}

	if(fclose(fp1)!=0)
	{
		printf("fclose(fp1) error\n");
		return NULL;
	}
	if(fclose(fp2)!=0)
	{
		printf("fclose(fp2) error\n");
		return NULL;
	}
	flatg=1;
	return NULL;
}

void *NextCopy(void *arg)
{
	if(flatg==0)
		sleep(1);
	FILE *fp1=NULL,*fp2=NULL;
	fp1=fopen("./myfile1","r");
	if(fp1==NULL)
	{
		printf("fp1=fopen error\n");
		return NULL;
	}
	fp2=fopen("./myfile2","a");
	if(fp2==NULL)
	{
		printf("fp2=fopen error\n");
		return NULL;
	}

	int size=*(int*)arg;
	fseek(fp1,size/2,SEEK_SET);
	for(int i=0;i<size/2;i++)
	{
		char ch;
		ch=fgetc(fp1);
		fputc(ch,fp2);
	}

	if(fclose(fp1)!=0)
	{
		printf("fclose(fp1) error\n");
		return NULL;
	}
	if(fclose(fp2)!=0)
	{
		printf("fclose(fp2) error\n");
		return NULL;
	}
	flatg=2;
	return NULL;

}


int main(int argc, const char *argv[])
{
	pthread_t thread1,thread2;

	FILE *fp=fopen("./myfile1","r");
	if(fp==NULL)
		ERROR_MSG("fp=fopen error");
	fseek(fp,0,SEEK_END);
	int size=ftell(fp);
	if(fclose(fp)!=0)
		ERROR_MSG("fclose(fp) error");

	if(pthread_create(&thread1,NULL,PrevCopy,(void*)&size)!=0)
	{	
		printf("pthread_create error\n");
		return -1;
	}

	if(pthread_create(&thread2,NULL,NextCopy,(void*)&size)!=0)
	{	
		printf("pthread_create error\n");
		return -1;
	}
	while(1)
		if(flatg==2)
			return 0;
}

运行结果:



 

2.创建两个线程,一个线程实现字符串的逆置,另一个线程打印字符串,并要求打印顺序是

一正一反交替打印 flag

eg:

hello

olleh

hello

olleh

#include <myhead.h>

int flag=0;

typedef struct 
{
	char str[100];
	int len;
}str,*strptr;

void *TurnStr(void *arg)
{
	int i,j;
	char ch;
	if(flag==1)
		sleep(1);
	while(1)
	{
		for(i=0,j=((strptr)arg)->len-1;i<=((strptr)arg)->len/2;i++,j--)
		{
			ch=((strptr)arg)->str[i];
			((strptr)arg)->str[i]=((strptr)arg)->str[j];
			((strptr)arg)->str[j]=ch;
		}
		flag=1;
		sleep(1);
	}
	return NULL;
}

void *PutOut(void *arg)
{
	if(flag==0)
		sleep(1);
	while(1)
	{
		fputs(((strptr)arg)->str,stdout);
		putchar(10);
		flag=0;
		sleep(1);
	}
}


int main(int argc, const char *argv[])
{
	pthread_t thread1,thread2;

	str str1;
	puts("输入字符:");
	fgets(str1.str,sizeof(str1.str),stdin);
	putchar(10);
	str1.len=strlen(str1.str);

	if(pthread_create(&thread1,NULL,TurnStr,(void*)&str1)!=0)
	{	
		printf("pthread_create error\n");
		return -1;
	}

	if(pthread_create(&thread2,NULL,PutOut,(void*)&str1)!=0)
	{	
		printf("pthread_create error\n");
		return -1;
	}

	while(1);
	return 0;
}

运行结果:


3.牛客网


网站公告

今日签到

点亮在社区的每一天
去签到