首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >患有PTHREADS的偏执狂?

患有PTHREADS的偏执狂?
EN

Stack Overflow用户
提问于 2014-05-19 18:16:06
回答 2查看 128关注 0票数 1

在我看过的所有地方,我都找到了关于如何使用带有指向函数调用参数的指针的p线程的教程和示例,该函数调用引用了主函数中的全局变量或局部变量。另一方面,由于我不能使用全局变量,所以我有以下代码:

代码语言:javascript
运行
复制
pthread_t thread;

void *thread_created(void *np);
void function2(int numParam);

void function1(int numParam)
{
    int cond=0;
    ...
    if (cond)
        {
            pthread_attr_t attr;
            pthread_attr_init(&attr);
            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
            pthread_create(&thread,&attr,thread_created,&numParam);
        }
}

void *thread_created(void *np)
{
    int numParam;
    numParam=*((int *)np);
    function2(numParam);
    return NULL;
}

void function2(int numParam)
{
}

但是,在我看来,在某些情况下,function1中的局部变量function1可能会在线程有机会获得其值之前超出范围。种族状况。因此,我修改了代码,添加了标记为//<的行--

代码语言:javascript
运行
复制
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;    //<--
pthread_cond_t condition=PTHREAD_COND_INITIALIZER;  //<--
pthread_t thread;

void *thread_created(void *np);
void function2(int numParam);

void function1(int numParam)
{
    int cond=0;
    ...
    if (cond)
        {
            pthread_attr_t attr;
            pthread_attr_init(&attr);
            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
            pthread_mutex_lock(&mutex);                 //<--
            pthread_create(&thread,&attr,thread_created,&numParam);
            pthread_cond_wait(&condition,&mutex);       //<--
            pthread_mutex_unlock(&mutex);               //<--
        }
}

void *thread_created(void *np)
{
    int numParam;
    pthread_mutex_lock(&mutex);         //<--
    numParam=*((int *)np);
    pthread_cond_signal(&condition);    //<--
    pthread_mutex_unlock(&mutex);       //<--
    function2(numParam);
    return NULL;
}

void function2(int numParam)
{
}

我是不是太偏执了?这里真的有比赛条件吗?或者,当pthread_create返回时,局部变量已经被复制,我可以继续了吗?会不会有太多的偏执狂?我提出这个问题的原因是,我在我的系统中还有其他几个类似的例子,我不想把它弄得乱七八糟,而且由于我没有在其他地方见过它,我觉得我的“修复”被夸大了。

致以问候。

阿尔弗雷多·梅拉兹

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-19 20:36:32

使用全局互斥和条件变量是一种非常糟糕的方法。它基本上序列化了所有线程创建操作。有几种向新线程传递参数的更好方法:

  1. 最好的方法是:如果您的数据是一个整数,可以通过对void *的强制转换来忠实地表示,那么就这样做。这不需要任何同步,也不需要分割内存。或者,如果您不想假设您可以像这样通过void *进行转换,则可以通过const char dummy[N];支持较小的整数值0N,然后将dummy+i传递给pthread_create,然后从线程启动函数中接收到的指针参数中减去dummy。这个变体是100%便携式,即C标准所要求的。
  2. 光同步:将线程参数放入结构中,并向结构中添加一个sem_t成员。将结构放在父线程的堆栈上(调用pthread_create函数中的自动存储)。让父线程在创建线程之前调用sem_init,在pthread_create返回后调用sem_wait。新线程访问完参数后调用sem_post (例如,将它们复制到自己的本地存储空间),父线程在sem_wait返回后调用sem_destroy。此时,新线程不再使用参数结构,因此父线程可以关闭它,让它超出范围,等等。
  3. 中度同步:malloc。父线程通过malloc为参数分配存储空间,新线程负责调用free。我认为这种适度的同步是因为,即使malloc通常尝试使用线程-本地竞技场,当内存在一个线程中分配并在另一个线程中释放时,也存在一个基本的全局同步类的代价(尽管这一成本可能会被推迟)。当然,这种方法也有潜在的内存碎片成本,以及处理分配失败路径的复杂性成本。
票数 2
EN

Stack Overflow用户

发布于 2014-05-20 02:17:36

使用R. response,这是最后的代码,以防有人需要它:

代码语言:javascript
运行
复制
pthread_t thread;
sem_t semaphore;

void initialize_semaphore()
{
    sem_init(&semaphore,0,1);
}

void destroy_semaphore()
{
    sem_destroy(&semaphore);
}

void *thread_created(void *np);
void function2(int numParam);

void function1(int numParam)
{
    int cond=0;
    ...
    if (cond)
        {
            pthread_attr_t attr;
            pthread_attr_init(&attr);
            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
            pthread_create(&thread,&attr,thread_created,&numParam);
            sem_wait(&semaphore);
        }
}

void *thread_created(void *np)
{
    int numParam;
    numParam=*((int *)np);
    sem_post(&semaphore);
    function2(numParam);
    return NULL;
}

void function2(int numParam)
{
}

谢谢大家的回答。

致以问候。

阿尔弗雷多·梅拉兹。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23744537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档