线程基础知识汇总

什么是线程?
线程就是轻量级的进程
多线程的优点:线程之间除了栈区的内容其他的都是共享的
               缺点:互斥与同步
那么,什么时候使用多线程,什么时候使用多进程呢?
1、当创建和销毁较频繁使用线程,因为创建进程的花销比较大
2、需要传输大量数据使用线程,因为多线程切换速度快,不需要跨越进程边界
3、安全稳定选进程,快速频繁选线程

线程相关函数
1、创建线程
#include <pthead.h>
int pthread_create(pthread_t *thread,const pthread_attr_t  *attr,void *(*start_routine(void *),void *arg));
参数一:pthread _t *
参数二:线程的属性,一般设置为NULL
参数三:函数的指针(函数名) void *  (void *)
参数四:主线程给子线程通过该参数传值
 并且在编译时要连接pthread库        -lpthread

2、等待子线程结束
#include <pthread.h>
int pthread_join(pthread_t thread,void **retval);
 参数一:pthread_t
参数二:子线程给主线程传值  NULL

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

void *thread(void *arg)
{
    while(1)
    {
    printf("Hello\n");
    sleep(1);
    }
}

void * thread2(void * arg)
{
    while(1)
    {
    printf("world\n");
    sleep(1);
    }
}

int main()
{
    //创建线程
    pthread_t pid1,pid2;
    pthread_create(&pid1,NULL,thread1,NULL);
    //参数一:pthread_t *
    //参数二:线程的属性
    //参数三:函数的指针 void *函数名(void *)
    //参数四:主线程的子线程的子线程通过该参数传值
    pthread_create(&pid2,NULL,thread2,NULL);
    
    //等待线程结束
    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
    return 0;
}

3、线程退出
(1)主动退出
#include <pthraed.h>
void pthread_exit(void *retval);
参数:NULL,线程结束时不带值

void *thread1(void *arg)
{
    int i=0;
    while(1)
    {
        if(5==i)
        {
        pthread_exit(NULL);//线程主动退出,表示该线程退出不带出来值
        }
    printf("Hello world\n");
    sleep(1);
    }
}

(2)被动取消
#include <pthraed.h>
int pthread_cancel(pthread_t thread);
 参数:线程的ID号

    int i=0;
    while(1)
    {
        if(i>5)
        {
        pthread_cancel(pid2);//参数:线程的ID号
        }
        printf("main pthread\n");
        sleep(1);
        j++;
    }

前面提到了线程之间除了栈区其他都是共享的,也就是说全局变量与堆区数据都是共享的,可以通过代码做一个小测试

#include <stdio.h>
#include <prthead.h>

int a=10;
void *pthread1(void *arg)
{
    a+=10;
    printf("pthread1 a=%d\n",a);
}

void *pthread2(void *arg)
{
    a+=20;
    printf("pthread a=%d\n",%d);
}

int main()
{
    pthraed_t pid1,pid2;
    pthread_create(&pid1,NULL,thread1,NULL);
    pthread_create(&pid2,NULL,thread2,NULL);
    a+=15;
    printf("main pthread a=%d\n",a);
    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
    return 0;
}

通过以上代码就可以得到,
main thread a=25
pthread1 a=35
pthread a=55,由此就可以得出结论

对堆区的数据也可以采用相同的方法验证

线程之间的通信

1、主线程给子线程传值
通过创建线程的第四个参数让主线程给子线程传值

2、子线程给主线程传值
通过exit(),pthread()函数配合使用,通过exit()函数的参数与pthread_join()函数的第二个参数实现子线程给主线程传值

线程中需要解决的问题

1、互斥:多线程不允许同时访问临界资源
        互斥锁的作用:互斥锁主要用来保护临界资源
        每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源
        线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止

互斥锁的相关函数:
初始化互斥锁:
#include <pthread.h>
函数原型:int pthread_mutex_init(pthread_mutex_t * mutex,pthread_muexattr_t * attr)
参数一:mutex :互斥锁
参数二:互斥锁:互斥锁属性//NULL表示缺省属性
返回值:
成功:0
失败:-1

申请互斥锁:
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t * mutex)
参数:mutex:互斥锁
返回值:
成功:0
失败:-1

释放互斥锁:
#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t * mutex)
函数参数:mutex:互斥锁
函数返回值:
成功:0
出错:-1

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

char str[20]={'\0'};
//定义一个全局的锁,多线程公用一个互斥锁
pthread_mutex_t mymutex;

void *thread(*arg)
{
    char *pc=(char *)arg;
    //将主线程传过来的值一个一个赋值
    //申请锁
    pthread_mutex_lock(&mymutex);
    int i=0;
    while(*pc)
    {
        str[i]=*pc;
        pc++;
        i++;
        sleep(1);
        printf("%s\n",str);
    }
    str[i]='\0';
    printf("%s\n",str);
    //释放锁
    ptfread_mutex_unlock(&mymutex);
}

int main()
{
    char str1[20]="0123456789";
    char str2[20]="abcdefghij";
    char str3[20]="ABCDEFGHIJ";

    //初始化互斥锁
    pthread_mutex_init(&mumutex,NULL);
    //创建3个线程
    pthread_t pid1,pid2,pid3;
    pthread_create(&pid1,NULL,thread,str1);
    pthread_create(&pid2,NULL,thread,str2);
    pthread_create(&pid3,NULL,thread,str3);
    //等待结束
    pthread_join(pid1,NULL);
    pthread_join(pid2,NULL);
    pthread_join(pid3,NULL);
}

 同步:多线程去访问临界资源时,按照一定的操作顺序来访问。

信号量:
有名信号量:多进程实现同步
无名信号量:多线程同步
信号灯采集:多进程实现同步

信号量的引用:

更新中...
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值