Linux 线程

主要围绕以下图形来写

345原则

1.创建线程

原型:

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

  当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于定制各种不同的线程属性,暂可以把它设置为NULL,以创建默认属性的线程。

  新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。

示例代码

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 
void* fun1(void*arg)
{
        printf(" thread is create\n  T1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);
}
int main()
{

 int ret;
 pthread_t t1;
 int param=100;

ret=pthread_create(&t1,NULL,fun1,(void*)&param);

if(ret==0)
        {
        printf("main: Creat t1 is success\n");
        }

        printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

 pthread_join (t1,NULL);

return  0;

}

该代码中传递的参数为整型数,可修改为其他类型。

2.线程的退出和等待

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

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

  如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态。

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,void *(*start_rtn)(void*),void *arg);
//int pthread_join(pthread_t thread,void **value_ptr);
//void pthread_exit(void *retval);


void* fun1(void*arg)
{
        static int ret =12;
        printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);
        pthread_exit((void*)&ret);
 

}
int main()
{
 int*pret=NULL;
 int ret;
 pthread_t t1;
 int param=100;

ret=pthread_create(&t1,NULL,fun1,(void*)&param);

if(ret==0)
        {
        printf("main: Creat t1 is success\n");
        }

        printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

       pthread_join (t1,(void**)&pret);

        printf("Main: t1 quit:%d\n",*pret);
return  0;

}

返回值为 整型数

当返回值为字符串时,示例代码如下

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,void *(*start_rtn)(void*),void *arg);
//int pthread_join(pthread_t thread,void **value_ptr);
//void pthread_exit(void *retval);


void* fun1(void*arg)
{
        static char *p="t1 is run out!";
        printf(" thread is create\n  T1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);

        pthread_exit((void*)p);

}
int main()
{
 char*pret=NULL;
 int ret;
 pthread_t t1;
 int param=100;

ret=pthread_create(&t1,NULL,fun1,(void*)&param);

if(ret==0)
        {
        printf("main: Creat t1 is success\n");
        }

        printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

        pthread_join (t1,(void**)&pret);

        printf("Main: t1 quit:%s\n",pret);
return  0;

}

3.线程之 共享内存验证

示例代码如下

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 
int g_data=0;
void* fun1(void*arg)
{
        printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);

        while(1)
        {
                printf("T1 :data is %d\n",g_data++);
                sleep(1);
        }
}


void* fun2(void*arg)
{
        printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);

        while(1)
        {
                printf("T2 :data is %d\n",g_data++);
                sleep(1);
        }
}
int main()
{

 int ret;
 pthread_t t1;
 pthread_t t2;
 int param=100;

ret=pthread_create(&t1,NULL,fun1,(void*)&param);
if(ret==0)
        {
        printf("main: Creat t1 is success\n");
        }


ret=pthread_create(&t2,NULL,fun2,(void*)&param);
if(ret==0)
        {
        printf("main: Creat t2 is success\n");
        }

        printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

        while(1)
        {
                printf("Main :data is %d\n",g_data++);
                sleep(1);
        }
 pthread_join (t1,NULL);
 pthread_join (t2,NULL);
return  0;

}

运行结果如下

main: Creat t1 is success
thread is create
T1 id is :140556216985344
param is 100
T1 :data is 0
thread is create
T2 id is :140556208592640
param is 100
T2 :data is 1
main: Creat t2 is success
Main id is :140556225271552
Main :data is 2
T1 :data is 3
Main :data is 5
T2 :data is 4
T1 :data is 6
Main :data is 7
T2 :data is 8
T1 :data is 9
T2 :data is 10
Main :data is 11
T1 :data is 12
T2 :data is 13

证明三个线程共同再争夺内存资源

4.互斥量加锁和解锁

原型:

创建和销毁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t mutex);

加锁和解锁

int pthread_mutex_lock(pthread_mutex_t mutex);
int pthread_mutex_unlock(pthread_mutex_t mutex);

示例代码如下:

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *mutex);
//int pthread_mutex_lock(pthread_mutex_t *mutex);
//int pthread_mutex_unlock(pthread_mutex_t *mutex);
int g_data=0;
pthread_mutex_t key;
void* fun1(void*arg)
{
        int i=0;
        pthread_mutex_lock(&key);
        for(i=0;i<=5;i++)
        {
         printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
         sleep(1);
        }
        pthread_mutex_unlock(&key);
}


void* fun2(void*arg)
{
        printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
}

void* fun3(void*arg)
{
        printf("thread is create\nT3 id is :%ld\n",(unsigned long)pthread_self());//get id
}

int main()
{

 int ret;
 pthread_t t1;
 pthread_t t2;
 pthread_t t3;


pthread_mutex_init(&key,NULL);
ret=pthread_create(&t1,NULL,fun1,NULL);
if(ret==0)
        {
        printf("main: Creat t1 is success\n");
        }


ret=pthread_create(&t2,NULL,fun2,NULL);
if(ret==0)
        {
        printf("main: Creat t2 is success\n");
        }

ret=pthread_create(&t3,NULL,fun3,NULL);
if(ret==0)
        {
        printf("main: Creat t3 is success\n");
        }

        printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

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

pthread_mutex_destroy(&key);
return 0;
}

运行结果如下:

main: Creat t1 is success
thread is create
T1 id is :140546299254528
main: Creat t2 is success
thread is create
T2 id is :140546290861824
main: Creat t3 is success
Main id is :140546307540736
thread is create
T3 id is :140546282469120
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528

这段代码主要是给fun1加锁了,从运行结果中可以看到 fun1中的循环都是成对的

5.互斥锁限制共享资源的访问

为了实现 让g_data=3时让fun1线程退出这个功能,可以在循环开始前给他加锁,在g_data=3条件成立时给他解锁,然后执行exit(0)操作,让线程fun1退出。

示例代码如下:

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *mutex);
//int pthread_mutex_lock(pthread_mutex_t *mutex);
//int pthread_mutex_unlock(pthread_mutex_t *mutex);
pthread_mutex_t key;
int g_data=0;
void* fun1(void*arg)
{
        printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);
        pthread_mutex_lock(&key);
        while(1)
        {
                printf("T1 :data is %d\n",g_data++);
                sleep(1);
                if(g_data==3)
                {

                        pthread_mutex_unlock(&key);
                        printf("T1 is quit =================!\n");
//                      pthread_exit(NULL);
                        exit(0);
                }
        }

}


void* fun2(void*arg)
{
        printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);

        while(1)
        {
                printf("T2 :data is %d\n",g_data);
                pthread_mutex_lock(&key);
                g_data++;
                pthread_mutex_unlock(&key);
                sleep(1);
        }
}
int main()
{

 int ret;
 pthread_t t1;
 pthread_t t2;
 int param=100;
 pthread_mutex_init(&key,NULL);
ret=pthread_create(&t1,NULL,fun1,(void*)&param);
if(ret==0)
        {
        printf("main: Creat t1 is success\n");
        }


ret=pthread_create(&t2,NULL,fun2,(void*)&param);
if(ret==0)
        {
        printf("main: Creat t2 is success\n");
        }

        printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

        while(1)
        {
                printf("Main :data is %d\n",g_data);
                sleep(1);
        }
 pthread_join (t1,NULL);
 pthread_join (t2,NULL);
 pthread_mutex_destroy(&key);
return  0;
}

运行结果如下:

main: Creat t1 is success
thread is create
T1 id is :140554397001472
param is 100
T1 :data is 0
thread is create
T2 id is :140554388608768
param is 100
T2 :data is 1
main: Creat t2 is success
Main id is :140554405287680
Main :data is 1
T1 :data is 1
Main :data is 2
T1 :data is 2
Main :data is 3
T1 is quit =================!

从运行结果可以发现,当data等于3时,T1退出了

6. 条件控制

原型:

条件的创建与销毁:

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t cond);

等待和触发:

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_signal(pthread_cond_t cond);

对于刚才让g_data=3时让fun1线程退出还有另一种办法,就是使用条件来实现

具体方法:在fun1中一直等待,在fun2中判断 如果g_data=3时,让条件进行触发,然后fun1中等待收到了信号,往下执行。

示例代码如下:

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *mutex);
//int pthread_mutex_lock(pthread_mutex_t *mutex);
//int pthread_mutex_unlock(pthread_mutex_t *mutex);

//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//int pthread_cond_destroy(pthread_cond_t cond);
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
//int pthread_cond_signal(pthread_cond_t cond);
//int pthread_cond_broadcast(pthread_cond_t cond);
pthread_mutex_t key;
pthread_cond_t cond;
int g_data=0;
void* fun1(void*arg)
{
        printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);
        pthread_mutex_lock(&key);
        while(1)
        {
                pthread_cond_wait(&cond,&key);
                printf("T1 run ==========================\n");
                printf("T1 :data is %d\n",g_data);

                g_data=0;
                sleep(1);
        }

}


void* fun2(void*arg)
{
        printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);

        while(1)
        {
                printf("T2 :data is %d\n",g_data);
                pthread_mutex_lock(&key);
                g_data++;
                if(g_data==3)
                {
                        pthread_cond_signal(&cond);
                }
                pthread_mutex_unlock(&key);
                sleep(1);
        }
}

int main()
{
 int ret;
 pthread_t t1;
 pthread_t t2;
 int param=100;
 pthread_mutex_init(&key,NULL);
 pthread_cond_init(&cond,NULL);
ret=pthread_create(&t1,NULL,fun1,(void*)&param);
if(ret==0)
        {
//rintf("main: Creat t1 is success\n");
        }
ret=pthread_create(&t2,NULL,fun2,(void*)&param);
if(ret==0)
        {
//rintf("main: Creat t2 is success\n");
        }
//      printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
 pthread_join (t1,NULL);
 pthread_join (t2,NULL);

 pthread_mutex_destroy(&key);
 pthread_cond_destroy(&cond);
return  0;

}

7.初始化的两种方法

在进行初始化操作时,有两种方法:

分别为动态初始化和静态初始化

动态初始化:

pthread_mutex_t mutex;  //dynamic init
pthread_cond_t cond;      //dynamic init

主函数中必须:

pthread_mutex_init(&mutex, NULL);   //dynamic init
pthread_cond_init(&cond, NULL);       //dynamic init

使用宏进行初始化(静态初始化):

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // static init
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // static init

下面是示例代码:

#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
//int pthread_mutex_destroy(pthread_mutex_t *mutex);
//int pthread_mutex_lock(pthread_mutex_t *mutex);
//int pthread_mutex_unlock(pthread_mutex_t *mutex);

//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//int pthread_cond_destroy(pthread_cond_t cond);
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
//int pthread_cond_signal(pthread_cond_t cond);
//int pthread_cond_broadcast(pthread_cond_t cond);
pthread_mutex_t key=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
int g_data=0;
void* fun1(void*arg)
{
        printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);
        pthread_mutex_lock(&key);
        while(1)
        {
                pthread_cond_wait(&cond,&key);
                printf("T1 run ==========================\n");
                printf("T1 :data is %d\n",g_data);

                g_data=0;
                sleep(1);
        }

}


void* fun2(void*arg)
{
        printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
        printf("param is %d\n",*(int*)arg);

        while(1)
        {
                printf("T2 :data is %d\n",g_data);
                pthread_mutex_lock(&key);
                g_data++;
                if(g_data==3)
                {
                        pthread_cond_signal(&cond);
                }
                pthread_mutex_unlock(&key);
                sleep(1);
        }
}
int main()
{

 int ret;
 pthread_t t1;
 pthread_t t2;
 int param=100;
// pthread_mutex_init(&key,NULL);
// pthread_cond_init(&cond,NULL);
ret=pthread_create(&t1,NULL,fun1,(void*)&param);
if(ret==0)
        {
//rintf("main: Creat t1 is success\n");
        }


ret=pthread_create(&t2,NULL,fun2,(void*)&param);
if(ret==0)
        {
//rintf("main: Creat t2 is success\n");
        }

//      printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id

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

 pthread_mutex_destroy(&key);
 pthread_cond_destroy(&cond);
return  0;

}

在使用静态初始化时,只需要通过宏定义来初始化就行,不需要再一次在main函数中进行初始化。

以上是线程的所有内容。

(师: 上官可编程)
  • 33
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux线程通信是指在Linux操作系统中,不同线程之间进行信息交流和数据共享的机制。线程通信是多线程编程中非常重要的一部分,它可以实现线程之间的协作和同步。 在Linux中,线程通信可以通过以下几种方式实现: 1. 共享内存:多个线程可以通过共享内存区域来进行数据的读写。线程可以访问同一块内存区域,从而实现数据的共享。需要注意的是,由于多个线程同时访问共享内存可能会导致数据竞争和不一致性问题,因此需要使用互斥锁或其他同步机制来保证数据的一致性。 2. 信号量:信号量是一种用于线程同步的机制,它可以用来控制对共享资源的访问。通过使用信号量,线程可以等待某个条件满足后再继续执行,或者通知其他线程某个条件已经满足。 3. 互斥锁:互斥锁是一种用于保护共享资源的机制,它可以确保在同一时间只有一个线程可以访问共享资源。当一个线程获得了互斥锁后,其他线程需要等待该线程释放锁才能继续执行。 4. 条件变量:条件变量是一种用于线程同步的机制,它可以让线程等待某个条件满足后再继续执行。条件变量通常与互斥锁一起使用,以确保在等待条件时不会发生竞争条件。 5. 管道:管道是一种用于进程间通信的机制,但在Linux中也可以用于线程间通信。通过管道,一个线程可以将数据写入管道,另一个线程可以从管道中读取数据。 6. 消息队列:消息队列是一种用于进程间通信的机制,但在Linux中也可以用于线程间通信。通过消息队列,一个线程可以将消息发送到队列中,另一个线程可以从队列中接收消息。 7. 套接字:套接字是一种用于网络通信的机制,但在Linux中也可以用于线程间通信。通过套接字,不同线程可以通过网络协议进行通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

火鸡味の锅巴

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

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

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

打赏作者

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

抵扣说明:

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

余额充值