Linux线程的概念及线程的控制

线程分为主线程和新线程,谁先运行是随机的,由调度器决定。
线程强调资源共享,进程强调资源独占。
但有些资源是每个线程各有一份的:线程id;上下文,包括各种寄存器的值、程序计数器和栈指针;栈空间;errno变量;信号屏蔽字;调度优先级。
线程共享资源:⽂件描述符表、每种信号的处理⽅式、当前工作⽬录、用户id和组id
线程库函数pthread是由POSIX标准定义的,在Linux下线程函数位于libpthread共享库中,因此在编译时要加上-lpthread选项。
线程与进程的区别:
进程是系统进行资源分配和调度的一个独立单位,线程是CPU调度和分派的基本单位;
Linux下,没有真正意义的线程,Linux下的线程是用进程模拟的;
线程是进程内部的执行流,在进程的地址空间内运行。
线程的控制:
1、创建线程

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
void* thread_run(void* arg)
{
  int i=0; 
  while(i++<5)
  {
  printf("newthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
  sleep(1);
  }
  return NULL;
}
int main()
{
    pthread_t id;
    int ret=pthread_create(&id,NULL,thread_run,NULL);
    if(ret!=0)
    {
      perror("pthread_create");
      printf("%s",strerror(ret));
      return 1;
    }
    int i=0;
    while(i++<5)
    {
    printf("mainthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
    sleep(3);
    }
    return 0;
}

运行结果:
这里写图片描述
2、线程的等待及终止线程
a、从线程函数return,这种方法对主线程不适用,从main函数return相当于exit。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
void* thread_run(void* arg)
{
  int i=0; 
  while(i++<5)
  {
  printf("newthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
  sleep(1);
  }
  return (void*)10;
}
int main()
{
    pthread_t id;
    int ret=pthread_create(&id,NULL,thread_run,NULL);
    if(ret!=0)
    {
      perror("pthread_create");
      printf("%s",strerror(ret));
      return 1;
    }
    int i=0;
    while(i++<5)
    {
    printf("mainthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
    sleep(3);
    }
    void* val;
    pthread_join(id,&val);
    printf("newthread was return,tid:%lu ,pid:%d exit code is:%d\n",pthread_self(),getpid(),(int)val);
    return 0;
}

运行结果:
这里写图片描述
b、⼀个线程可以调⽤pthread_cancel终⽌同⼀进程中的另一个线程

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
void* thread_run(void* arg)
{
  int i=0; 
  while(i++<5)
  {
  printf("newthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
  sleep(1);
  }
  //return (void*)10;
}
int main()
{
    pthread_t id;
    int ret=pthread_create(&id,NULL,thread_run,NULL);
    if(ret!=0)
    {
      perror("pthread_create");
      printf("%s",strerror(ret));
      return 1;
    }
    int i=0;
    while(i++<5)
    {
    printf("mainthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
    sleep(3);
    }
    pthread_cancel(id);
    void* val;
    pthread_join(id,&val);
    printf("newthread was return,tid:%lu ,pid:%d exit code is:%d\n",pthread_self(),getpid(),(int)val);
    return 0;
}

运行结果:
这里写图片描述
c、线程可以调用pthread_exit终⽌⾃己

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
void* thread_run(void* arg)
{
  int i=0; 
  while(i++<5)
  {
  printf("newthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
  sleep(1);
  }
  //return (void*)10;
  pthread_exit((void*)18);
}
int main()
{
    pthread_t id;
    int ret=pthread_create(&id,NULL,thread_run,NULL);
    if(ret!=0)
    {
      perror("pthread_create");
      printf("%s",strerror(ret));
      return 1;
    }
    int i=0;
    while(i++<5)
    {
    printf("mainthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
    sleep(3);
    }
    //pthread_cancel(id);
    void* val;
    pthread_join(id,&val);
    printf("newthread was return,tid:%lu ,pid:%d exit code is:%d\n",pthread_self(),getpid(),(int)val);
    return 0;
}

运行结果:
这里写图片描述
3、线程分离
在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。
默认情况下,线程被创建成可结合的。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
void* thread_run(void* arg)
{
  /*int i=0; 
  while(i++<5)
  {
  printf("newthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
  sleep(1);
  }
  return (void*)10;
  pthread_exit((void*)18);*/
  pthread_detach(pthread_self());
  printf("%s\n",(char*)arg);
  return NULL;
}
int main()
{
    pthread_t id;
    int ret=pthread_create(&id,NULL,thread_run,"thread1 run...");
    if(ret!=0)
    {
      perror("pthread_create");
      printf("%s",strerror(ret));
      return 1;
    }
    /*int i=0;
    while(i++<5)
    {
    printf("mainthread,  tid: %lu  pid: %d \n",pthread_self(),getpid());
    sleep(3);
    }
    pthread_cancel(id);
    void* val;
    pthread_join(id,&val);
    printf("newthread was return,tid:%lu ,pid:%d exit code is:%d\n",pthread_self(),getpid(),(int)val);*/
    int m=0;
    sleep(1);
    if(pthread_join(id,NULL)==0)
    {
      printf("pthread wait success!\n");
      return 0;
    }
    else
     {
       printf("pthread wait failed!\n");
       return 1;
     }
        return m;
}

运行结果:
这里写图片描述
4、线程同步与互斥
多个线程同时访问共享数据时可能会冲突,比如两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成:
1. 从内存读变量值到寄存器
2. 寄存器的值加1
3. 将寄存器的值写回内存
假设两个线程在多处理器平台上同时执行这三条指令,则可能导致最后变量只加了⼀次⽽非两次。
创建两个线程,各⾃把count增加5000次,正常情况下最后count应该等于10000,但事实上每次运行该程序的结果都不⼀样,有时候数到5000多,有时候数到6000多。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
int count=0; 
void* thread_run(void* arg)
{
  int i=5000;
  int val=0;
  while(i--)
  {
  int val=count;
  printf("newthread,  tid: %lu  count is: %d \n",pthread_self(),count);
  count=val+1;
  }
  return 0;
}
int main()
{
  pthread_t tid1;
  pthread_t tid2;
  pthread_create(&tid1,NULL,thread_run,NULL);
  pthread_create(&tid2,NULL,thread_run,NULL);
  pthread_join(tid1,NULL);
  pthread_join(tid2,NULL);
  printf("count is %d\n",count);
  return 0;
}

运行结果:
这里写图片描述
对于多线程的程序,访问冲突的问题是很普遍的,解决的办法是引入互斥锁(Mutex,MutualExclusive Lock),获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程,没有获得锁的线程只能等待而不能访问共享数据,这样“读-修改-写”三步操作组成一个原子操作,要么都执行,要么都不执⾏,不会执行到中间被打断,也不会在其它处理器上并行做这个操作。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
pthread_mutex_t mutex_lock=PTHREAD_MUTEX_INITIALIZER;//申请互斥锁
int count=0; 
void* thread_run(void* arg)
{
  int i=5000;
  int val=0;
  while(i--)
  {
  pthread_mutex_lock(&mutex_lock);//加锁
  int val=count;
  printf("newthread,  tid: %lu  count is: %d \n",pthread_self(),count);
  count=val+1;
  pthread_mutex_unlock(&mutex_lock);//解锁
  }
  return 0;
}
int main()
{
  pthread_t tid1;
  pthread_t tid2;
  pthread_create(&tid1,NULL,thread_run,NULL);
  pthread_create(&tid2,NULL,thread_run,NULL);
  pthread_join(tid1,NULL);
  pthread_join(tid2,NULL);
  printf("count is %d\n",count);
  return 0;
}

运行结果:
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值