マルチスレッドプログラミングの学習

スレッドと機能説明の概念

オペレーティングシステムの原理の点で、スレッドは、実行プロセスのパスです。すべてのスレッドは、これはまた、複数のスレッドが、このような仮想アドレス空間、ファイル記述子、および信号処理として、プロセスのシステムリソースのすべてを共有し、その上になることを意味し、同じプロセス空間で実行されています。しかし、同じプロセスで複数のスレッドが独自のコールスタック(コールスタック)は、ご使用の環境(レジスタコンテキスト)、自身のスレッドローカルストレージ(スレッドローカルストレージ)を登録。このプロセスは、異なるタスクを実行するために並列に各スレッドを、スレッドの多くを持つことができます。ここに画像を挿入説明

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

図1に示すように、機能説明:pthreand_create()スレッドを作成するために使用され、第3のパラメータstart_routineはの実装では、関数を指摘されています。
2、パラメーター:

  • 最初のパラメータは、彼がスレッドのスレッドIDを返すために使用され、スレッドポインタ型がpthread_tです。各スレッドはpthread_selfによって、自身のスレッドIDを取得することができます()
  • 二番目のパラメータは、プロパティのスレッドです
  • start_routineが第三のパラメータは、子スレッド作成されたタスクであるボイド*のFUNC(ボイド*)は、実行される関数プロトタイプを指し、関数ポインタであります
  • ここで、構造体を渡すことが要求される子スレッドパッケージに渡される複数のパラメータがある場合第四引数argは、起動に渡されるパラメータの関数です。

スレッドの属性

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_join等待它退出,否则子线程在结束时,内存资源不能得到释放造成内存泄漏,所以我们创建线程时一般会将线程设置为分离状态

线程编码示例

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
void *thread_worker1(void *args);
void *thread_worker2(void *args);

int main (int argc, char **argv)
{
    int shared_var = 1000;
    pthread_t    tid;//定义一个线程
    pthread_attr_t  thread_attr;//定义线程属性

if(pthread_attr_init(&thread_attr))//初始化线程
{
    printf("pthread_attr_init()failure:%s\n",strerror(errno));
    return -1;
}
if(pthread_attr_setstacksize(&thread_attr,120*1024))//设置线程属性栈的大小
{
    printf("pthread_attr_setstacksize()failure:%s\n",strerror(errno));
    return -2;
}
if(pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED))//设置线程为可分离状态
{
    printf("pthread_attr_setdetachstate()failure:%s\n",strerror(errno));
    return -3;
}
pthread_create(&tid,&thread_attr,thread_worker1,&shared_var);//&tid,用来返回该线程的id,第二个参数是线程的属性,第三个参数是子线程要完成的任务,第四个参数是传给所调用的函数的指针
printf("Thread worker1 tid[%ld]created ok\n",tid);

pthread_create(&tid,NULL,thread_worker2,&shared_var);
printf("Thread worker2 tid[%ld]created ok\n",tid);

pthread_attr_destroy(&thread_attr);//用完以后要摧毁

pthread_join(tid,NULL);//线程2需要主线程调用pthread_join等待它退出

while(1)
{
    printf("main thread shared_var:%d\n",shared_var);
    sleep(10);
}
}
void *thread_worker1(void *args)
{
    int  *ptr = (int *)args;
    if( !args )
    {
        printf("%s()get invalid arguments\n", __FUNCTION__);
        pthread_exit(NULL);
    }
    printf("Thread worker1 [%ld]start running..\n",pthread_self());//打印自己的线程id
    while(1)
    {
        printf("+++ %s before shared_var++:%d\n", __FUNCTION__,*ptr);
        *ptr+=1;//*ptr=*ptr+1
        sleep(2);
        printf("+++:%s after sleep shared_var:%d\n", __FUNCTION__,*ptr);
    }
    printf("Thread worker 1 exit...\n");

    return NULL;
}
void *thread_worker2(void *args)
{
    int    *ptr = (int *)args;
    printf("%s()get invalid arguments\n", __FUNCTION__);
    pthread_exit(NULL);

    printf("Thread worker2 [%ld]start running..\n",pthread_self());

    while(1)
    {
        printf("--- %s before shared_var++:%d\n", __FUNCTION__,*ptr);
        *ptr+=1;//* ptr=*ptr+1 
        sleep(2);
        printf("---:%s after sleep shared_var:%d\n", __FUNCTION__,*ptr);
    }
    printf("Thread worker 2 exit...\n");
    return NULL;
}

linux下vim代码运行结果:
ここに画像を挿入説明
该代码出现的问题:thread_worker1 在创建后首先开始运行,在开始自加之前值为初始值1000,然后让该值自加后休眠2秒后再打印该值发现不是1001而是1002了。这是由于shared_var 这个变量会被两个子线程同时访问修改致。如果一个资源会被不同的线程访问修改,那么我们把这个资源叫做临界资源,那么对于该资源访问修改相关的代码就叫做临界区。那么怎么解决多个线程之间共享同一个共享资源,是多线程编程需要考虑的一个问题。有关如何解决此临界问题!请关注我下一篇博客!

リリース3元の記事 ウォン称賛11 ビュー272

おすすめ

転載: blog.csdn.net/makunIT/article/details/104605225