Linux下多任务编程(线程)

线程(thread)

        (1)线程就是轻量级的进程;
        (2)线程都要依附于进程,进程要是结束了,进程中开辟的所有线程就结束了;
        (3)创建一个线程时,只开辟栈区,所以说线程效率高于进程,系统的开销小;
        (4)多线程是并发执行的,没有固定的先后顺序,具体执行顺序有操作系统的调度器和线程的调度策略决定。

进程和线程的区别

        线程是轻量级的进程,只新建栈区;进程拥有4个区(堆区、栈区、全局区、代码区)
        进程之间不能相互访问对方的内存;线程共享全局区,所以可以访问同一个全局区变量

创建线程

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                    void *(*start_routine) (void *), void *arg);

typedef long pthread_t;    //将long型重定义成pthread_t

        功能:创建线程 
        参数:pthread_t *thread         线程的id 参数地址传递方式获取线程id
                   const pthread_attr_t *attr         设置线程的属性 通常赋值为NULL忽略
                   void *(*start_routine) (void *)         函数指针 线程执行的函数
                   void *arg         就是给第三个参数线程执行函数传递参数的

        返回值:成功返回 0,失败返回 -1

阻塞等待一个子线程结束     

#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);

        功能:阻塞等待子线程结束,回收线程的资源。
        参数:pthread_t thread         线程id 阻塞等待的子进程编号
                   void **retval         用来保存线程结束时的返回值的,通常赋值为NULL
        返回值:成功返回 0,失败返回 -1

静态库和共享库

        静态库:是以.a结尾的库文件,在编译的时候去静态库找函数远吗,将函数源码编译到程序中,因此体积大,但在运行的时候不需要再加载静态库。

        共享库:是以.so结尾的库文件,也叫动态库。在编译的时候去动态库中找函数地址,将函数地址编译到程序中,因此体积小,但是运行的时候需要根据地址去动态库加载函数。

线程的互斥(重点)

什么是互斥(重点)

        一个进程可以拥有多个线程,其中每个线程共享该进程的所有资源。但是由于线程共享了进程的资源和地址空间,因此任何线程对系统资源的操作都会给其他线程带来影响。
        多线程在访问共享资源时,线程的同步和互斥问题就非常重要了。

        互斥:任何时刻一个线程在访问共享资源时,其他线程只能阻塞等待。

解决互斥问题

        (1)利用互斥锁来解决
        (2)使用信号量来解决

互斥锁使用方法

        (1)创建互斥锁       pthread_mutex_t mutex;        全局区
        (2)初始化锁          pthread_mutex_init(&mutex,NULL);        主函数
        (3)加锁                 pthread_mutex_lock(&mutex);        子线程
        (4)解锁                 pthread_mutex_unlock(&mutex);

线程的同步(重点)

什么是同步

        多个线程要按照一定的顺序相互配合完成某个任务。

信号量(semaphore)

        

信号量使用方法

        (1)创建信号量        sem_t sem;
        (2)初始化信号量        sem_init(&sem,0,1);
                 第2个参数是0代表共享
                 第3个参数是1代表解决互斥问题,是0代表解决同步问题。
        (3)请求信号量        sem_wait(&sem); 请求成功,共享资源数-1,请求失败,阻塞等待
        (4)释放信号量        sem_post(&sem); 释放信号量,共享资源数+1

        功能:信号量初始化

#include "my.h"
typedef struct
{
    char name[30];
    int age;
}stu_t;
void *fun(void *p)
{
    int *q=p;
    while(1)
    {
        printf("age is %d\n",*q);
        printf("age is %d\n",*((int*)p));
        sleep(1);
    }
}
void *func1(void *p)
{
    char *q=p;
    while(1)
    {
        printf("name is %s\n",q);
        printf("name is %s\n",(char *)p);
        sleep(1);
    }
}
void* func3(void *p)
{
    stu_t *q=p;
    while(1)
    {
        printf("name is %s ,age is %d\n",q->name,q->age);
        printf("name is %s ,age is %d\n",((stu_t*)p)->name,((stu_t*)p)->age);
        sleep(1);
    }
}
int main(int argc, const char *argv[])
{
    int age=18;
    char name[100]="zhangteng";
    stu_t s1;
    s1.age=age;
    strcpy(s1.name,name);
    pthread_t id;
    pthread_t id2;
    pthread_t id3;
    pthread_create(&id,NULL,fun,&age);
    pthread_create(&id2,NULL,func1,name);
    pthread_create(&id3,NULL,func3,&s1);

    getchar();//阻塞等待输入一个字符
    return 0;
}
/* demo3.c 字符串 */
#include <stdio.h>
#include <pthread.h>
void *func1(void *arg)
{
        static int ret = 10;
        static char *p = "t1 is run out";
        printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t1:param is %d\n",*((int *)arg));
        pthread_exit((void *)p);
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        char *pret = NULL;
        ret = pthread_create(&t1, NULL, func1, (void *)&param);
        if(ret == 0){
                printf("main:create t1 success\n");
        }
        printf("main: %ld\n",(unsigned long)pthread_self());
//      while(1);
        pthread_join(t1,(void **)&pret);
        printf("main: t1 quit: %s\n",pret);
        return 0;
}
/* demo2.c 数据 */
#include <stdio.h>
#include <pthread.h>
void *func1(void *arg)
{
        static int ret = 10;

        printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t1:param is %d\n",*((int *)arg));

        pthread_exit((void *)&ret);
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;

        int *pret = NULL;

        ret = pthread_create(&t1, NULL, func1, (void *)&param);
        if(ret == 0){
                printf("main:create t1 success\n");
        }
        printf("main: %ld\n",(unsigned long)pthread_self());
//      while(1);
        pthread_join(t1,(void **)&pret);

        printf("main: t1 quit: %d\n",*pret);

        return 0;
}
/* demo1.c */
#include <stdio.h>
#include <pthread.h>
void *func1(void *arg)
{
        printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t1:param is %d\n",*((int *)arg));
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;

        ret = pthread_create(&t1, NULL, func1, (void *)&param);
        if(ret == 0){
                printf("create t1 success\n");
        }
        printf("main: %ld\n",(unsigned long)pthread_self());
//      while(1);
        pthread_join(t1,NULL);

        return 0;
}

Linux多线程编程初探 - 峰子_仰望阳光 - 博客园 (cnblogs.com)

测试脚本shell

vi test.sh

./a.out
./a.out
./a.out

 编辑指令:chmod +x test.sh

 运行指令:./test.sh


vi test.c

int main()
{
    int i;
    for(i=0;i<100;i++){
        system("./a.out");
    }
}

 2、互斥锁

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

int g_data = 0;
pthread_mutex_t mutex;

void *func1(void *arg)
{
        int i;
        pthread_mutex_lock(&mutex);
        for(i=0;i<5;i++){
                printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
                printf("t1:param is %d\n",*((int *)arg));
                sleep(1);
        }
        pthread_mutex_unlock(&mutex);
}
void *func2(void *arg)
{
        pthread_mutex_lock(&mutex);

        printf("t2:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t2:param is %d\n",*((int *)arg));

        pthread_mutex_unlock(&mutex);
}
void *func3(void *arg)
{
        pthread_mutex_lock(&mutex);

        printf("t3:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t3:param is %d\n",*((int *)arg));

        pthread_mutex_unlock(&mutex);
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;
        pthread_t t3;

        pthread_mutex_init(&mutex, NULL);

        ret = pthread_create(&t1, NULL, func1, (void *)&param);
        if(ret == 0){
                printf("main:create t1 success\n");
        }
        ret = pthread_create(&t2, NULL, func2, (void *)&param);
        if(ret == 0){
                printf("main:create t2 success\n");
        }
        ret = pthread_create(&t3, NULL, func3, (void *)&param);
        if(ret == 0){
                printf("main:create t3 success\n");
        }
        printf("main: %ld\n",(unsigned long)pthread_self());

        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_join(t3,NULL);

        pthread_mutex_destroy(&mutex);

        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值