6、程序、进程、线程(二)

linux下的线程

与传统的进程相比,用线程来实现相同的功能有如下优点:

  1. 系统资源消耗低
  2. 速度快
  3. 线程间的数据共享比进程间容易的多

编写linux下的线程需要包含头文件pthread.h

一个简单的多线程例子:

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

static int run = 1;//运行状态参数
static int retvalue;//线程返回值

void *start_routine(void *arg) { //线程处理函数
    int *running = arg;
    printf("子线程初始化完毕, 传入参数为 %d\n",*running);

    while(*running) {
        printf("子线程正在运行\n");
        usleep(1);
    }
    printf("子线程退出\n");

    retvalue = 8;
    pthread_exit((void*)&retvalue);
}

int main(int argc, char *argv[]) {
    pthread_t pt;
    int ret = -1;
    int times = 3;
    int i = 0;
    int *ret_join = NULL;

    ret = pthread_create(&pt, NULL, (void*)start_routine, &run);//建立线程

    if(ret != 0 ) {
        puts("建立线程失败");
        return 1;
    }
    usleep(1);

    for(;i<times;i++) {
        puts("主线程打印");
        usleep(1);
    }
    run = 0; //设置线程控制值,让线程退出
    pthread_join(pt, (void*)&ret_join);
    printf("线程返回值为 :%d\n",*ret_join);

    return 0;
}

编译的时候记得要指定线程库gcc pthread.c -lpthread -o pthread

linux下的线程创建函数 pthread_create
#include <pthread.h>

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

//Compile and link with -pthread.

第一个参数是线程标识符,第二个参数用于设置线程的属性,为NULL时采用默认属性。第三个参数是一个返回值为void*,参数为void*的函数,是线程分配完资源后要执行的部分。线程函数运行时传入的参数,也就是第三个参数的函数需要传入的参数。

当线程创建成功时返回 0 ,否则表示失败了。常见的错误代码有EAGAIN、EINVAL,EAGAIN表示系统中的线程达到了上线,EINVAL表示线程的属性非法。线程创建成功后新创建的先按照参数3和4执行,原来的线程在线程创建函数返回后继续执行下一行代码。

线程的结束函数pthread_join、pthread_exit

函数pthread_join用来等待一个线程运行结束,这个函数是阻塞函数

#include <pthread.h>

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

//Compile and link with -pthread.

第一个参数是线程标识符,第二个参数是线程结束后返回的值。

线程函数(上述为start_routine)的结束方式有两种,一种是线程函数运行结束,不用返回结果,另一种是通过线程函数pthread_exit函数结束,函数的参数为 被捕获的返回值。

#include <pthread.h>

void pthread_exit(void *retval);

//Compile and link with -pthread.

线程的属性

在上面用pthread_create创建函数的时候,使用了默认参数,即将第二个参数设为NULL,通常来说建立一个线程时使用默认属性就行了,但是很多时候需要调整线程的属性,特别是线程的优先级。

线程的属性结构

pthread_attr_t


线程属性的初始化函数是pthread_attr_init,这个函数必须在pthread_create之前调用。属性对象主要包括 线程的摘取状态、调度优先级、运行栈地址、运行栈大小、优先级。

#include <pthread.h>

int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);

//Compile and link with -pthread.
线程优先级

线程优先级是经常设置的属性,由两个函数进行控制,pthread_attr_getschedparam获得线程的优先级设置;函数pthread_attr_setschedparam设置线程的优先级。

#include <pthread.h>

int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);

Compile and link with -pthread.

线程的优先级存放在结构sched_param中,其操作方式是先将优先级取出来,设置完后再放回去,

互斥锁与信号量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Little BigUs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值