• 3、Linux多线程,线程同步


    5)线程私有数据

        进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有。但有时线程也需要保存自己的私有数据,这时可以创建线程私有数据(Thread-specific DateTSD来解决。在线程内部,私有数据可以被各个函数访问,但对其他线程是屏蔽的。例如我们常见的变量errno,它返回标准的出错信息。它显然不能是一个局部变量,几乎每个函数都应该可以调用它;但它又不能是一个全局变量,否则在A线程里输出的很可能是B线程的出错信息。要实现诸如此类的变量,我们就必须使用线程数据。我们为每个线程数据创建一个键,它和这个键相关联,在各个线程里,都使用这个键来指代线程数据,但在不同的线程里,这个键代表的数据是不同的,在同一个线程里,它代表同样的数据内容。

        线程私有数据采用了一键多值的技术,即一个键对应多个数值,访问数据时好像是对同一个变量进行访问,但其实是在访问不同的数据。

        创建私有数据的函数有4个:pthread_key_create(创建), pthread_setspecific(设置), pthread_getspecific(获取), pthread_key_delete(删除)

    #include <pthread.h>

    int pthread_key_creadte(pthread_key_t *key,void (*destr_fuction) (void *));

    int pthread_setspecific(pthread_key_t key,const void * pointer));

    void * pthread_getspecific(pthread_key_t key);

    int pthread_key_delete(ptherad_key_t key);

    6)线程同步

        线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和异步信号。

    1)互斥锁(mutex

        通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。

    int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);

    int pthread_mutex_lock(pthread_mutex *mutex);

    int pthread_mutex_destroy(pthread_mutex *mutex);

    int pthread_mutex_unlock(pthread_mutex *

    (1)先初始化锁init()或静态赋值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER

    attr_t有:

    PTHREAD_MUTEX_TIMED_NP:其余线程等待队列

    PTHREAD_MUTEX_RECURSIVE_NP:嵌套锁,允许线程多次加锁,不同线程,解锁后重新竞争

    PTHREAD_MUTEX_ERRORCHECK_NP:检错,与一同,线程请求已用锁,返回EDEADLK;

    PTHREAD_MUTEX_ADAPTIVE_NP:适应锁,解锁后重新竞争

    (2)加锁,lock,trylock,lock阻塞等待锁,trylock立即返回EBUSY

    (3)解锁,unlock需满足是加锁状态,且由加锁线程解锁

    (4)清除锁,destroy(此时锁必需unlock,否则返回EBUSY,//Linux下互斥锁不占用内存资源

    示例代码

    #include <cstdio>
    #include <cstdlib>
    #include <unistd.h>
    #include <pthread.h>
    #include "iostream"
    
    using namespace std;
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    int tmp;
    
    void* thread(void *arg)
    {
        cout << "thread id is " << pthread_self() << endl;
    	pthread_mutex_lock(&mutex);
    	tmp = 12;
    	cout << "Now a is " << tmp << endl;
    	pthread_mutex_unlock(&mutex);
    	return NULL;	
    }
    
    int main()
    {
        pthread_t id;
    	cout << "main thread id is " << pthread_self() << endl;
        tmp = 3;
    	cout << "In main func tmp = " << tmp << endl;
    	if (!pthread_create(&id, NULL, thread, NULL))
    	{
    	    cout << "Create thread success!" << endl;
    	}
    	else
    	{
    	    cout << "Create thread failed!" << endl;
    	}
    	pthread_join(id, NULL);
    	pthread_mutex_destroy(&mutex);
    	return 0;
    }
    

    编译: g++ -o thread testthread.cpp -lpthread

    说明:pthread库不是Linux系统默认的库,连接时需要使用静态库libpthread.a,所以在使用pthread_create()创建线程,以及调用pthread_atfork()函数建立fork处理程序时,需要链接该库。在编译中要加 -lpthread参数。

  • 相关阅读:
    php静态调用非静态方法
    phalcon 框架3.0更新时报错
    centos7.5更换docker-ce镜像源
    腾讯云更换镜像源遇到的坑
    php cli模式下调试
    审查php.ini自动分析程序
    docker WARNING: IPv4 forwarding is disabled. Networking will not work.
    git常用命令,制作缩写命令
    学习GRPC(一) 简单实现
    mac与linux服务器之间使用ssh互通有无
  • 原文地址:https://www.cnblogs.com/mydomain/p/2138455.html
Copyright © 2020-2023  润新知