线程同步 ----互斥锁

线程的创建:     

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

该函数会在进程中创建一个新线程,函数的各参数描述如下:
      o 第一个参数thread是一个指向pthread_t对象的指针,当线程成功创建后,新线程
        的ID会存储在thread指向的pthread_t对象中。
      o 第二个参数attr,指定新建线程的属性。如果attr为NULL,则创建线程时使用默认的属
        性。线程创建完成之后仍可使用相关函数来改变线程的属性,
      o 第三个参数start_routine是一个函数指针(即函数的首地址),它是新建线程的入口,新
        创建的线程从start_routine这个地址开始运行。从上面的定义来看,该函数指针所指向
        的函数有两个特征:
                        函数返回值为 void * 类型
                        该函数有一个类型为 void * 类型的参数
      o 第四个参数arg。start_routine所指向的函数有一个类型为 void * 的参数,即为这里
        的 void *arg


返回值:
        如果线程创建成功,则pthread_create函数返回0;否则返回一个非0值,该非0值是代
        表一个错误码来指示出错类型。


等待线程结束函数:

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

形  参:    thread     被等待的线程标识符            retval     一个用户定义的指针,它可以用来存储被等待线程的返回值    说  明:这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
 
 

线程终止函数:

 
 
void pthread_exit(void* retval);
retval     函数的返回指针,只要pthread_join中的第二个参数retval不是NULL,这个值将被传递给retval。
 
 
线程取消函数:
 
 
int pthread_cancel(pthread_t thread);
成功返回0;失败返回错误码。


互斥锁
  通过锁的机制实现线程间的互斥,同一时刻只有一个线程可以锁定它,当一个锁被某个线程锁定的时候,如果有另外一个线程尝试锁定这个临界区(互斥体),则第二个线程会被阻塞,或者说被置于等待状态。只有当第一个线程释放了对临界区的锁定,第二个线程才能从阻塞状态恢复运行。

 

int pthread_mutex_init(pthread_mutex_t* mutex, const thread_mutexattr_t* mutexattr);初始化一个互斥锁。

参数:
mutex:互斥锁地址。类型是 pthread_mutex_t 。
attr:设置互斥量的属性,通常可采用默认属性,即可将 attr 设为 NULL。
可以使用宏 PTHREAD_MUTEX_INITIALIZER 静态初始化互斥锁,比如:
pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
这种方法等价于使用 NULL 指定的 attr 参数调用 pthread_mutex_init() 来完成动态初始化,不同之处在于 PTHREAD_MUTEX_INITIALIZER 宏不进行错误检查。
返回值:
成功:0,成功申请的锁默认是打开的。
失败:非 0 错误码


  

int pthread_mutex_lock(pthread_mutex_t* mutex);如果mutex被锁定,当前进程处于等待状态;否则,本进程获得互斥锁并进入临界区。

参数:
mutex:互斥锁地址。
返回值:
成功:0
失败:非 0 错误码


int pthread_mutex_trylock(pthread_mutex_t* mutex);
和lock不同的时候,尝试获得互斥锁不成功不会使得进程进入阻塞状态,而是继续返回线程执行。该函数可以有效避免循环等待锁,如果trylock失败可以释放已经占有的资源,这样可以避免死锁。

调用该函数时,若互斥锁未加锁,则上锁,返回 0;若互斥锁已加锁,则函数直接返回失败,即 EBUSY。


int pthread_mutex_unlock(pthread_mutex_t* mutex);
释放互斥锁,并使得被阻塞的线程获得互斥锁并执行。

参数:
mutex:互斥锁地址。
返回值:
成功:0
失败:非 0 错误码


int pthread_mutex_destroy(pthread_mutex_t* mutex);用来撤销互斥锁的资源

参数:
mutex:互斥锁地址。
返回值:
成功:0
失败:非 0 错误码



--------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------

#include <stdio.h>  
#include <pthread.h>  
#include <unistd.h>  
  
pthread_mutex_t mutex; //互斥锁  
  
void printer(char *str)  
{  
    pthread_mutex_lock(&mutex); //上锁  
    while(*str!='\0')  
    {  
        putchar(*str);    
        fflush(stdout);  
        str++;  
        sleep(1);  
    }  
    printf("\n");   
    pthread_mutex_unlock(&mutex); //解锁  
}  
  
// 线程一  
void *thread_fun_1(void *arg)  
{  
    char *str = "hello";  
    printer(str); 
}  
  
// 线程二  
void *thread_fun_2(void *arg)  
{  
    char *str = "world";  
    printer(str);  
}  
  
int main(void)  
{  
    pthread_t tid1, tid2;  
      
    pthread_mutex_init(&mutex, NULL); //初始化互斥锁  
      
    // 创建 2 个线程  
    pthread_create(&tid1, NULL, thread_fun_1, NULL);  
    pthread_create(&tid2, NULL, thread_fun_2, NULL);  
  
    // 等待线程结束,回收其资源  
    pthread_join(tid1, NULL);  
    pthread_join(tid2, NULL);   
      
    pthread_mutex_destroy(&mutex); //销毁互斥锁  
      
    return 0;  
}  
测试如下:

gcc 1.c -lpthread 编译 

[root@libmaster zxd]# ./a.out 
hello
world 

不加锁打印:

[root@libmaster zxd]# ./a.out 
hwoerllldo


猜你喜欢

转载自blog.csdn.net/linuxzhuxiaodi/article/details/77720278