2

我正在学习 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。但是,代码目前只给了我 30 次“这是来自线程 2”的信息。我相信有什么问题

*argsa = *(args*) arg; 

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

任何帮助,将不胜感激!

4

3 回答 3

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;
}
于 2012-06-02T21:06:07.337 回答
2

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

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

  2. 用 分配这样的结构malloc

  3. 填写结构。

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

  5. 当线程完成结构后,线程将其释放。

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

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

于 2012-06-03T02:03:13.260 回答
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
于 2013-07-31T21:58:53.963 回答