Linux C多线程编程-线程互斥

简介:

Linux下的多线程编程需要注意的是程序需要包含头文件pthread.h,在生成可执行文件的时候需要链接库libpthread.a或者libpthread.so

线程创建函数:

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

参数说明:

Thread 标示一个线程,它是一个pthread_t类型的变量(unsigned long int

attr 用于设置线程的属性,默认是null

start_routine当线程分配资源成功后,线程中所运行的单元,通俗的说就是你自己写的一个函数

Arg线程函数运行时传入的一个参数,一般可以用这个传入的参数去控制线程结束

函数返回值:

创建成功返回0,创建失败返回非0值,常见错误返回代码为EAGAINEINVALEGAIN标示系统中线程的数量达到上限,错误代码EINVAL表示线程的属性非法。

注意:线程创建城成功后,新创建的线程按照参数3和参数4确定一个运行函数,原来的线程在线程创建函数返回后继续运行下一行代码。

 

 

线程结束函数:pthread_join()和pthread_exit()

pthread_join()用来等待一个线程运行结束。这个函数是阻塞函数,一直被等待的线程结束为止,函数才返回并且收回被等待线程的资源。函数的原型为:

Extern int pthread_join_P((pthread_t _th,void **__thread_return));

_th:线程的标示符,也就是线程创建成功的值,在通俗的说就是pthread_create函数运行成功后的第一个参数

__thread_return:返回值,它是一个指针用来存贮被等待线程的返回值。

 

线程函数的结束方式有两种:一种是线程函数运行结束,不用返回结果;另一种就是通过函数pthread_exit()来实现,将结果传出。

函数原型是:

Extern void pthread_exit_P((void*_retval))

参数是函数的返回值,这个值可以被pthread_join函数捕获,通过__thread_return参数获得此值。

 

说道线程的创建还有一点必须要提及,那就是线程的属性。一般在我们创建线程的时候设置attr属性的时候都是使用null,这个是默认参数。但是在很多时候需要调整线程的属性,特别是线程优先级。

线程的属性结构为:pthread_attr_t,在头文件<pthreadtype.h>中定义

typedef struct

{

       int                              detachstate;   线程的终止状态

       int                              schedpolicy;  线程调度策略(优先级)

       struct sched_param           schedparam;  线程的调度参数

       int                              inheritsched;  线程的继承性

       int                               scope;       线程的作用域

       size_t                          guardsize;   线程栈末尾的警戒缓冲区大小

       int                               stackaddr_set;  运行栈

       void *                         stackaddr;   线程栈的位置

       size_t                          stacksize;    线程栈的大小

}pthread_attr_t;

要注意的是线程的属性值不能直接设置,必须要用先关的函数进行操作。线程属性的初始化函数pthread_attr_init(),这个函数必须在pthread_create()函数之前调用。

线程间的互斥:

线程的互斥函数有:互斥函数的初始化pthread_mutex_init(),互斥函数的锁定函数pthread_mutex_lock(),互斥函数的预锁定函数pthread_mutex_trylock(),互斥函数的解锁函数pthread_mutex_unlock(),互斥函数的销毁函数pthread_mutex_destroy()

 

废话不多说,上代码:

#include <stdio.h>

#include <pthread.h>

 #include <unistd.h>

#define MUXNUMBER 10

pthread_mutex_t test_mutex;

int testi = 0;

int testis[10 * 1000];

int count=0;

 

void testfun(void)

{

testis[testi] = testi * 2;

usleep(1000);

testi++;

}

 

void thread_func()

{

    int m_count=0;

   while(m_count<1000)

   {

       pthread_mutex_lock(&test_mutex);

       testfun();

       pthread_mutex_unlock(&test_mutex);

       m_count++;

       //sleep(1);

   }

}

 

int main()

{

    pthread_t t[10];

    pthread_mutex_init(&test_mutex,NULL);

    int i;

    for(i=0;i<MUXNUMBER;i++)

    {

        if(pthread_create(&t[i],NULL,(void*)thread_func,NULL) == -1)

        {

            printf("create  Thread error !\n");

            exit(1);

        }

        //sleep(1);

    }

 

    for(i=0;i<MUXNUMBER;i++)

    {

         pthread_join(t[i],NULL);

        //sleep(1);

    }

 

    pthread_mutex_destroy(&test_mutex);

    for(i=0;i<10000;i++)

    {

        if(testis[i]!=i*2)

        {

            printf("%d个数据出错!:%d\n",i,testis[i]);

        }

 

    }

    return 0;

}














本文转自xsster51CTO博客,原文链接:http://blog.51cto.com/12945177/1930296 ,如需转载请自行联系原作者




相关文章
|
6天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
11 3
|
6天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
9 2
|
6天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
16 2
|
6天前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
14 1
|
14天前
|
监控 安全 算法
线程死循环确实是多线程编程中的一个常见问题,在编码阶段规避潜在风险
【10月更文挑战第12天】线程死循环确实是多线程编程中的一个常见问题,在编码阶段规避潜在风险
38 2
|
16天前
|
监控 安全 算法
线程死循环确实是多线程编程中的一个常见问题,它可能导致应用程序性能下降,甚至使整个系统变得不稳定。
线程死循环是多线程编程中常见的问题,可能导致性能下降或系统不稳定。通过代码审查、静态分析、日志监控、设置超时、使用锁机制、测试、选择线程安全的数据结构、限制线程数、使用现代并发库及培训,可有效预防和解决死循环问题。
34 1
|
20天前
|
监控 安全 算法
线程死循环是多线程编程中的常见问题,可能导致应用性能下降甚至系统不稳定。
【10月更文挑战第6天】线程死循环是多线程编程中的常见问题,可能导致应用性能下降甚至系统不稳定。为了解决这一问题,可以通过代码审查、静态分析、添加日志监控、设置超时机制、使用锁和同步机制、进行全面测试、选用线程安全的数据结构、限制线程数量、利用现代并发库,并对团队进行培训等方法来预防和减少死循环的发生。尽管如此,多线程编程的复杂性仍需要持续监控和维护以确保系统稳定。
43 3
|
23天前
|
安全 Java 开发者
在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制
【10月更文挑战第3天】在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制,如`synchronized`关键字、`Lock`接口及其实现类(如`ReentrantLock`),还有原子变量(如`AtomicInteger`)。这些工具可以帮助开发者避免数据不一致、死锁和活锁等问题。通过合理选择和使用这些机制,可以有效管理并发,确保程序稳定运行。例如,`synchronized`可确保同一时间只有一个线程访问共享资源;`Lock`提供更灵活的锁定方式;原子变量则利用硬件指令实现无锁操作。
15 2
|
22天前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
16 0
Linux C/C++之线程基础
|
26天前
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解