Linux中pthread_create傳遞參數(shù)的若干情況

0.背景介紹

  • 今天在工作中要使用pthread_create函數(shù)開啟一個線程,并且需要傳遞參數(shù),其中遇到了一些問題,現(xiàn)在來總結(jié)一下。

1.pthread_create介紹

  • 函數(shù)原型:
int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, (void*)(*start_rtn)(void*),void *arg);
  • 第一個參數(shù)為指向線程標識符的指針(例如:pthread_t p_thread)
  • 第二個參數(shù)用來設(shè)置線程屬性
  • 第三個參數(shù)是線程運行函數(shù)的起始地址
  • 第四個參數(shù)是運行函數(shù)的參數(shù)
  • 在Linux系統(tǒng)中如果希望開啟一個新的線程,可以使用pthread_create函數(shù),它實際的功能是確定調(diào)用該線程函數(shù)的入口點,在線程創(chuàng)建以后,就開始運行相關(guān)的線程函數(shù)。
頭文件 #include<pthread.h>
  • pthread_create的返回值表征進程是否創(chuàng)建成功。其中0:成功,-1:失敗。
  • 編譯的時候,需要添加編譯條件 -pthread。例如:g++ pthread_test.cpp -o pthread_test -pthread

2.pthread_create開啟線程,傳遞參數(shù)的幾種情況

2.1不傳遞參數(shù)

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string>

using namespace std;

pthread_t pid;

void* thread_no_argv(void* argv)
{   
    while(1)
    {
        cout << "i am new thread"<< endl;
        sleep(1);
    }
}

int main()
{
    pthread_create(&pid,NULL,thread_no_argv,NULL);
    pthread_detach(pid);//回收線程資源

    while(1)
    {
    }
    return 0;
}

2.2 傳遞一個簡單類型

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string>

using namespace std;

pthread_t pid;

void* thread_int_argv(void* argv)
{   
    int i = *(int*)argv;//進行類型裝換,具體的類型具體轉(zhuǎn)換
    while(1)
    {
        cout << "i am new thread"<< endl;
        cout << "i:" << i << endl;
        sleep(1);
    }
}

int main()
{
    int i = 10;

    pthread_create(&pid,NULL,thread_int_argv,(void*)&i);//最后一個參數(shù)為void*類型,傳遞變量的地址,其實其他的類型也遵循這個原則
    pthread_detach(pid);

    while(1)
    {
    }
    return 0;
}

2.3傳遞一個結(jié)構(gòu)體對象

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string>

using namespace std;

pthread_t pid;

typedef struct 
{
    int i;
    std::string str;
}my_adt;

void* thread_struct_argv(void* argv)
{   
    my_adt* adt = (my_adt*)argv;

    while(1)
    {
        cout << "i am new thread"<< endl;
        cout << "i:" << adt->i << endl;
        cout << "str:" << adt->str << endl;
        sleep(1);
    }
}

int main()
{
    my_adt adt;
    adt.i = 22;
    adt.str = "walter";

    pthread_create(&pid,NULL,thread_struct_argv,(void*)&adt);
    pthread_detach(pid);

    while(1)
    {
    }
    return 0;
}

2.4傳遞一個類對象

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <iterator>
#include <vector>

using namespace std;

pthread_t pid;

class A
{
public:
    int get_i()
    {
        return m_i;
    }

    void set_i(int i)
    {
        m_i = i;
    }

    std::string get_str()
    {
        return m_str;
    }

    void set_str(std::string str)
    {
        m_str = str;
    }

private:
    int m_i;
    std::string m_str;
};


class B
{
public:
    A get_a()
    {
        return m_a;
    }

    void set_a(A a)
    {
        m_a = a;
    }

    std::vector<std::string > get_iplist()
    {
        return m_iplist;
    }

    void set_iplist(std::vector<std::string> iplist)
    {
        m_iplist = iplist;
    }

private:
    A m_a;
    std::vector<std::string> m_iplist;
};

void* thread_object_argv(void* argv)
{   
    B *b = (B*)argv;

    A a = b->get_a();
    std::vector<std::string> iplist = b->get_iplist();

    cout << "a.i:" << a.get_i() << endl;
    cout << "a.str:" << a.get_str() << endl;
    cout << "iplist.size:" << iplist.size();
    for(std::vector<std::string>::iterator iter = iplist.begin();iter != iplist.end();iter++)
    {
        cout << "iplist:" << std::string(*iter) << endl;
    }


    while(1)
    {
        sleep(1);
    }
}

int main()
{
    A a;
    a.set_i(99);
    a.set_str("zx");

    std::vector<std::string> iplist;
    iplist.push_back("1.1.1.1");
    iplist.push_back("2.2.2.2");

    B *b = new B();//注釋1
    b->set_a(a);
    b->set_iplist(iplist);


    pthread_create(&pid,NULL,thread_object_argv,(void*)b);
    pthread_detach(pid);

    while(1)
    {
    }
    return 0;
}
  • 注釋1:這個地方最好使用new一個對象的方式,這樣可以為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,否則的話就可能會出現(xiàn)內(nèi)存分配的異常:std::bad_alloc。

總結(jié)

  • 上面介紹了幾種常用的傳遞參數(shù)的情況,在實際的情況中靈活變通使用。
  • 如果上面介紹的情況有什么問題,還請大家指出了,或者一起討論,或者還有什么更好的方法,也希望和我交流。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容