C中的多线程:传递结构

时间:2012-06-02 21:01:50

标签: c multithreading pointers

我正在学习C中的多线程性能。当我尝试编写示例代码时,我遇到了一个问题:

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

typedef struct{
    int a;
    char b;
    } args;

void* some_func (void* arg)
{
    args *argsa = malloc(sizeof(args));
//copy the content of arg to argsa, 
//so changes to arg in main would not affect argsa
    *argsa = *(args*) arg; 
    int i = 10;
    for (; i > 0; i--)
    {
        usleep (1); //to give other threads chances to cut in
        printf ("This is from the thread %d\n", argsa->a);
    }
    free (argsa);
}
int main()

{
    pthread_t thread[3];
    args ss;
    int index = 0;
    ss.b = 's';
    for (; index <3 ; index++)
    {
        ss.a = index;
        if (pthread_create (thread+index, NULL, some_func, (void*)&ss ))
        {
            usleep(10);
            printf ("something is wrong creating the thread"); 
        }
    }
        pthread_join ( thread[0], NULL);
        pthread_join ( thread[1], NULL);
        pthread_join ( thread[2], NULL);
    return 0;
}

我知道结构中的char b是无用的,但我只想练习传递一个结构。 我希望代码打印出来“这是来自线程x”,其中x是0,1或2,或者。但是,代码目前只给我“这是从线程2”30次。

我认为有问题
*argsa = *(args*) arg; 

但我找不到解决方法并获得所需输出的方法。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:3)

因为您将相同的指针传递给所有线程。当线程0开始时,你已经将ss.a的值增加到1(然后是2)。

这更正确一点:

void* some_func (void* arg)
{
    args *argsa = (args*)arg;
    int i;
    for (i = 0; i < 10; i++)
    {
        usleep (1); //to give other threads chances to cut in
        printf ("This is from the thread %d\n", argsa->a);
    }
}
int main()
{
    pthread_t thread[3];
    args ss[3];
    int index;
    for (index = 0; index < 3; index++)
    {
        ss[index].a = index;

        if (pthread_create(&thread[index], NULL, some_func, &ss[index] ))
        {
            printf ("something is wrong creating the thread"); 
        }
    }
    pthread_join ( thread[0], NULL);
    pthread_join ( thread[1], NULL);
    pthread_join ( thread[2], NULL);
    return 0;
}

答案 1 :(得分:2)

用于解决此类问题的模式如下:

  1. 创建一个结构,用于保存您想要传递给线程的参数。

  2. 使用malloc

  3. 分配此类结构
  4. 填写结构。

  5. 将指针传递给线程的结构。

  6. 当线程完成结构时,线程释放它。

  7. 这假设您不需要从线程中获取任何信息。如果这样做,您可以更改它,以便加入线程的代码释放结构。这允许结构也保持一个回复 - 你加入线程,读取响应信息,然后释放结构。

    不需要特殊的锁定或同步,因为当新创建的线程存在时,它是唯一接触该结构的线程。

答案 2 :(得分:0)

对不起,伙计们,但我试图解决同样的问题,我认为还没有给出正确的答案,以解决问题。我自己尝试了这个,我想出了以下代码。现在,我编译并运行它并且它按照我的预期非常有效,但我仍然不相信“锁定主要和解锁子进程”是最优雅的解决方案,所以我想知道你对它的看法。非常感谢您的任何澄清。

以下是代码:

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

typedef struct{
    int a;
    char b;
    } args;

pthread_mutex_t lock;

void* some_func (void *arg) {
    args argsa = *(args*)arg;
    pthread_mutex_unlock(&lock);
    printf ("This is from the thread %d\n", argsa.a);
}

int main() {
    pthread_t thread[10];
    args ss;
    int i, index=0;
    ss.b = 's';

    if (pthread_mutex_init(&lock, NULL) != 0) {
        printf("\n mutex init failed\n");
        return 1;
    }

    for (index = 0; index < 10 ; index++)
    {
        pthread_mutex_lock(&lock);
        ss.a = index;
        printf("index=%d, ", ss.a);
        if (pthread_create (thread+index, NULL, some_func, (void*)&ss ))
        {
            usleep(10);
            printf ("something is wrong creating the thread"); 
        }
    }
    for(i=0;i<10;i++)
        pthread_join ( thread[0], NULL);
    return 0;
}

输出:

#./program
index=0, This is from the thread 0
index=1, This is from the thread 1
index=2, This is from the thread 2
index=3, This is from the thread 3
index=4, This is from the thread 4
index=5, This is from the thread 5
index=6, This is from the thread 6
index=7, This is from the thread 7
index=8, This is from the thread 8
index=9, This is from the thread 9