我是c语言中多线程编程的新手。我在linux中为两个线程实现了一个thread_create.c文件。但如果我想在通用多线程文件中使用#define n那么指针
就会出错代码:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#define n 5
struct print_args {
int times;
char characters;
};
void * print_sum(void * parameters) {
struct print_args * pp = (struct print_args *) parameters;
for(int i=0; i<= pp->times; i++) {
printf("%c", pp->characters);
fflush(stdout);
sleep(1);
}
return (void *)&(pp->times);
}
int main() {
pthread_t t[n];
srand(time(NULL));
struct print_args t_args[n];
char first = 'A';
int *t_returnValue[n];
for(int j=0; j<n; j++) {
t_args[j].times = rand() % 10;
t_args[j].characters = first;
first++;
}
for(int j=0; j<n; j++) {
pthread_create(&t[j], NULL, &print_sum, &t_args[j]);
}
for(int j=0; j<n; j++) {
pthread_join(t[j], (void **)&t_returnValue[j]);
}
first -= n;
for(int j=0; j<n; j++) {
printf("n T%c: Times %d", (char)first++, (*t_returnValue)[j]);
}
return 0;
}
输出:
ACEDBAEBDCAEDBEBADBADEADEADEEDDD TA: Times 6 TB: Times 65 TC: Times 4 TD: Times 66 TE: Times 1
每次,第二个和第四个线程都指向第一个字符(?),我看不到错误…
(*t_returnValue)[j]
这是错误的。你需要
*t_returnValue[j]
现场演示。
您在pthread_join
呼叫中转换为(void **)
掩盖了问题。
即t_returnValue
为32位,不是为64位。
改变:
int *t_returnValue[n];
为:
void *t_returnValue[n];
然后,把printf
改成:
printf("T%c: Times %zdn", (char) first++,
(ssize_t) *(int *) t_returnValue[j]);
下面是重构的代码:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#define n 5
struct print_args {
int times;
char characters;
};
void *
print_sum(void *parameters)
{
struct print_args *pp = (struct print_args *) parameters;
for (int i = 0; i <= pp->times; i++) {
printf("%c", pp->characters);
fflush(stdout);
sleep(1);
}
return (void *) &(pp->times);
}
int
main()
{
pthread_t t[n];
srand(time(NULL));
struct print_args t_args[n];
char first = 'A';
#if 0
int *t_returnValue[n];
#else
void *t_returnValue[n];
#endif
for (int j = 0; j < n; j++) {
t_args[j].times = rand() % 10;
t_args[j].characters = first;
first++;
}
for (int j = 0; j < n; j++) {
pthread_create(&t[j], NULL, &print_sum, &t_args[j]);
}
for (int j = 0; j < n; j++) {
#if 0
pthread_join(t[j], (void **) &t_returnValue[j]);
#else
pthread_join(t[j], &t_returnValue[j]);
#endif
}
first -= n;
#if 1
printf("n");
#endif
for (int j = 0; j < n; j++) {
#if 0
printf("n T%c: Times %d", (char) first++, (*t_returnValue)[j]);
#else
printf("T%c: Times %zdn", (char) first++,
(ssize_t) *(int *) t_returnValue[j]);
#endif
}
return 0;
}
在上面的代码中,我使用了cpp
条件来表示旧代码和新代码:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
注意:这可以通过通过unifdef -k
这是我现在得到的程序输出:
AECDBAEDCBAEDCBAEDCBAEDCBEDEDEDEDD
TA: Times 4
TB: Times 4
TC: Times 4
TD: Times 9
TE: Times 8