当前位置: 首页 > news >正文

Linux系统编程-DAY06

一、线程概念
进程和线程共同点:并发

1.线程属于某一个进程,线程不共享栈区
优点:比多进程节省资源,可以共享变量。
      线程启动时,需要在栈区开一个8M的空间,进程拿到的资源,对于线程是共享的。

2.概念:线程是轻量级进程,一般是一个进程中的多个任务
    进程是系统中最小的资源分配单位
    线程是系统中最小的执行单位

3.区别:
    1)线程的并发度比进程多一些
    2)创建开销不同,thread 8M, proc 3G
    3)thread 共享进程中的资源,除了栈区。进程,独立(写时复制 cow)
    4)线程稳定性稍差。
    5)进程可以申请到硬件资源,线程用进程拿到的资源
    
4.三方库: pthread  clone   posix(posix便于移植的)
    4.1 编写代码头文件: pthread.h
    4.2 编译代码加载库: -lpthread   library 
libpthread.so  (lib开头so结尾,共享库)
gcc 1.c -lpthread 

5.线程的设计框架    
    1.创建多线程 --->线程空间操作  --->线程资源回收
    int pthread_create(
    pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine) (void *), void *arg);
        eg: pthread_create(&tid, NULL, th, NULL);
    2.  arg  回调函数的参数,即参数3的指针函数参数。
返回值:成功 0
失败 错误码

6.pthrea_self(void)获取自己的tid号

7.线程的退出:
    1: 自行退出 --> 自杀 --> 子线程自己退出        void pthread_exit(void *retval);  exit  return p;
    2: 强制退出 --> 他杀 --> 主线程结束子线程    int pthread_cancel(pthread_t thread);

8.线程的回收
    不同与进程没有孤儿线程和僵尸线程。
      主线程结束任意生成的子线程都会结束。
      子线程的结束不会影响主线程的运行。
int pthread_join(pthread_t, thread, void **retva)
    join有阻塞的意思
      功能:通过该函数可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。

9.地址有三种:
0、栈区变量  错误,子线程结束该地址失效。
1、全局变量  失去意义,本质可以直接访问。
正确形式:
2、静态变量 
3、堆区变量malloc

10.分离属性:
    int pthread_deatch(pthread_t thread);
        1)可以放在th里面调用,参数写自己的id号
        2)主线程调用:填入刚才创建的线程的线程号。

11.线程清理函数
    void pthread_cleanup_push(void (*routine)(void *), void *arg);
        功能:注册一个线程清理函数
        参数,routine,线程清理函数的入口
        arg,清理函数的参数。
        返回值,无
    void pthread_cleanup_pop(int execute);
        功能:调用清理函数
        execute,非0  执行清理函数
        0 ,不执行清理

12.线程起进程后,起完多线程就会变成单线程

二、练习及其代码
1.创造线程

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *th1(void *arg)
{while (1){printf("打瓦\n");sleep(1);}
}void *th2(void *arg)
{while (1){printf("吃饭\n");sleep(1);}
}int	main(int argc, char **argv)
{pthread_t tid1,tid2;pthread_create(&tid1, NULL, th1, NULL);pthread_create(&tid1, NULL, th2, NULL);while (1){sleep(1);}return 0;
}

2.获得线程tid号

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *th1(void *arg)
{while (1){printf("打瓦 th1, tid:%ld\n",pthread_self());sleep(1);}
}void *th2(void *arg)
{while (1){printf("吃饭 th2, tid:%ld\n",pthread_self());sleep(1);}
}int	main(int argc, char **argv)
{pthread_t tid1,tid2;pthread_create(&tid1, NULL, th1, NULL);pthread_create(&tid1, NULL, th2, NULL);while (1){printf("main th, tid:%ld\n",pthread_self());sleep(1);}return 0;
}

3.strerror


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>int	main(int argc, char **argv)
{int i = 0 ;for(i=0;i<400;i++){printf("%d %s\n",i,strerror(i));}//system("pause");return 0;
}

4.线程的exit

#include <stdio.h>
#include <bits/pthreadtypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *th(void *arg)
{int i = 3;while(i--){printf("th,tid:%ld\n",pthread_self());sleep(1);}pthread_exit(NULL);
}int	main(int argc, char **argv)
{pthread_t tid;pthread_create(&tid, NULL, th, NULL);while (1){sleep(1);}//system("pause");return 0;
}

5.线程的cancel

#include <stdio.h>
#include <bits/pthreadtypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
void *th(void *arg)
{int i = 3;while(i--){printf("th,tid:%ld\n",pthread_self());sleep(1);}pthread_exit(NULL);
}int	main(int argc, char **argv)
{pthread_t tid;pthread_create(&tid, NULL, th, NULL);int i = 0;while (1){printf("main th, tid : %ld\n", pthread_self());sleep(1);++i;if(3 == i){pthread_cancel(tid);}}//system("pause");return 0;
}

6.线程的回收

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>void *th(void *arg)
{int i = 5;while(i--){printf("th tid:%ld\n", pthread_self());sleep(1);}return NULL;
}int	main(int argc, char **argv)
{pthread_t tid;pthread_create(&tid, NULL, th, NULL);pthread_join(tid, NULL);return 0;
}

7.线程join带返回值

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>void *th(void *arg)
{char *p = (char *)malloc(50);strcpy(p, "小凡是人机");sleep(3);return p;
}int	main(int argc, char **argv)
{pthread_t tid;pthread_create(&tid, NULL, th, NULL);void *ret;pthread_join(tid, &ret);printf("ret %s\n",(char*)ret);free(ret);return 0;
}

8.线程的共享特性


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>int a = 0;
void *th(void *arg)
{sleep(1);a += 10;return NULL;
}int	main(int argc, char **argv)
{pthread_t tid;printf("a is %d\n", a);pthread_create(&tid, NULL, th, NULL);pthread_join(tid, NULL);printf("a is %d\n", a);return 0;
}

9.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <pthread.h>typedef struct
{char name[50];int age;char addr[50];
}PER;void *th(void *arg)
{PER *per = (PER*)arg;printf("th: %s %d %s\n", per->name, per->age, per->addr);strcat(per->name, "Runa");return per;
}int main(int argc, char **argv)
{PER per;bzero(&per, sizeof(per));printf("input name:");fgets(per.name, sizeof(per.name), stdin);per.name[strlen(per.name) - 1] = '\0';char buf[5] = {0};printf("input age:");fgets(buf, sizeof(buf), stdin);per.age = atoi(buf);printf("input addr:");fgets(per.addr, sizeof(per.addr), stdin);per.addr[strlen(per.addr) - 1] = '\0';pthread_t tid;pthread_create(&tid, NULL, th, &per);void *ret = NULL;pthread_join(tid, &ret);printf("join ret: %s %d %s\n",per.name, per.age, ((PER*)ret)->addr);return 0;
}

10.线程的栈区自动回收

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void* th(void* arg)
{pthread_detach(pthread_self());  //栈区系统自动回收return NULL;
}int main(int argc, char** argv)
{int i = 0;pthread_t tid;for (i = 0; i < 50000; i++){int ret = pthread_create(&tid, NULL, th, NULL);if (ret != 0){break;}printf("%d\n", i);}system("pause");return 0;
}

11.线程的清除

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
void clean(void *arg)
{printf("this clean %s\n", (char*)arg);free(arg);
}
void* th(void* arg)
{strcpy((char* )arg,"hello world\n");printf("th,strcpy over\n");return NULL;
}int	main(int argc, char **argv)
{pthread_t tid;char* p = malloc(50);pthread_cleanup_push(clean,p);pthread_create(&tid,NULL,th,p);pthread_join(tid,NULL);printf("before pop\n");pthread_cleanup_pop(1);system("pause");return 0;
}

相关文章:

  • Opigno LMS 3.2.7 安装操作记录
  • pyspark实践
  • 火柴INIBOX专业矿机登场,碾压现有Initverse挖矿设备
  • YOLOv4:目标检测的新标杆
  • Pytest自动化测试框架搭建:Jenkins持续集成
  • AI学习搭档:开启终身学习新时代
  • torch cuda 版本安装
  • 【Java】DelayQueue
  • 5.27 day 30
  • 修改SpringBootApplication类的入参后,引用外部yml的启动命令要修改
  • Spring AI 本地Ollama
  • C++ 中的函数包装:std::bind()、std::function<>、函数指针与 Lambda
  • 一个开源的多播放源自动采集在线影视网站
  • 15.进程间通信(一)
  • c++复习_第一天(引用+小众考点)
  • 2025吉林CCPC 题解(前六题)
  • 【NLP基础知识系列课程-Tokenizer的前世今生第四课】生物信息中的 Tokenizer 策略:如何切开一段基因?
  • 【NLP基础知识系列课程-Tokenizer的前世今生第五课】从静态到可学:Tokenizer 的自适应演化之路
  • C/C++的OpenCV的锐化
  • ojs导入显示空白页错误信息
  • 专业网站定制服务/全网营销推广服务
  • 临泉网站建设/数据统计网站
  • 免费做网站软件2003/白酒营销策划方案
  • asp.net的网站开发/近期新闻热点事件简短
  • 公司官方网站制作/产品推广渠道有哪些方式
  • 中华人民住房和城乡建设部网站/百度推广查询