Gui*_*ari 2 c random time srand ucontext
这里需要一些帮助.
我想了解这段代码中发生了什么.
我正在尝试为函数内部创建tickets的TCP_t结构生成随机数ccreate.
问题是,每次执行此代码时,srand(time(NULL))它都会反复返回相同的"随机"数字序列,例如:
TID: 0 | TICKET : 103
TID: 1 | TICKET : 198
Run Code Online (Sandbox Code Playgroud)
所以我随着时间的推移将其播种,以生成真正随机的数字.
当我将种子放在newTicket函数内部时,它会在每次执行时带来不同的数字,但每个线程的数字都相同.以下是输出示例:
执行1:
TID: 0 | TICKET : 148
TID: 1 | TICKET : 148
Run Code Online (Sandbox Code Playgroud)
执行2:
TID: 0 | TICKET : 96
TID: 1 | TICKET : 96
Run Code Online (Sandbox Code Playgroud)
因此,经过一些研究,我发现我不应该在每次打电话时播种它,rand而只是在节目开始时播种一次.现在,在将种子放入main函数之后,它给了我分段错误,我没有IDEA为什么.
这可能是一个愚蠢的问题,但我真的想了解发生了什么.
不知怎的,种子搞砸了什么?我错过了什么吗?我应该以另一种方式生成随机数吗?
#include <ucontext.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MAX_TICKET 255
#define STACK_SIZE 32000
typedef struct s_TCB {
int threadId;
int ticket;
ucontext_t context;
} TCB_t;
void test();
int newTicket();
int newThreadId();
int ccreate (void* (*start)(void*), void *arg);
int threadId = 0;
int main(){
srand(time(NULL)); //<<<============== HERE = SEGMENTATION FAULT
ccreate((void*)&test, 0);
ccreate((void*)&test, 0);
}
int ccreate (void* (*start)(void*), void *arg){
if(start == NULL) return -1;
ucontext_t threadContext;
getcontext(&threadContext);
makecontext(&threadContext, (void*)start, 0);
threadContext.uc_stack.ss_sp = malloc(STACK_SIZE);
threadContext.uc_stack.ss_size = STACK_SIZE;
TCB_t * newThread = malloc(sizeof(TCB_t));
if (newThread == NULL) return -1;
int threadThreadId = newThreadId();
newThread->threadId = threadThreadId;
newThread->ticket = newTicket();
printf("TID: %d | TICKET : %d\n", newThread->threadId, newThread->ticket);
return threadThreadId;
}
int newThreadId(){
int newThreadId = threadId;
threadId++;
return newThreadId;
}
int newTicket(){
//srand(time(NULL)); //<<<============== HERE = IT PARTIALLY WORKS
return (rand() % (MAX_TICKET+1));
}
void test(){
printf("this is a test function");
}
Run Code Online (Sandbox Code Playgroud)
感谢所有在这里借给我的人.
对不起,如果代码太难读了.试图尽可能地简化它.
问题不在于srand(time(NULL)),而在于makecontext.
您可以通过sanatizer运行代码以确认:
gcc-6 -fsanitize=undefined -fsanitize=address -fsanitize=leak -fsanitize-recover=all -fuse-ld=gold -o main main.c
./main
ASAN:DEADLYSIGNAL
=================================================================
==8841==ERROR: AddressSanitizer: SEGV on unknown address 0x7fc342ade618 (pc 0x7fc340aad235 bp 0x7ffd1b945950 sp 0x7ffd1b9454f8 T0)
#0 0x7fc340aad234 in makecontext (/lib/x86_64-linux-gnu/libc.so.6+0x47234)
#1 0x400d2f in ccreate (/home/malko/Desktop/main+0x400d2f)
#2 0x400c19 in main (/home/malko/Desktop/main+0x400c19)
#3 0x7fc340a87f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
#4 0x400b28 (/home/malko/Desktop/main+0x400b28)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0x47234) in makecontext
==8841==ABORTING
Run Code Online (Sandbox Code Playgroud)
您可以通过在创建上下文之前设置堆栈大小来解决问题:
char stack[20000];
threadContext.uc_stack.ss_sp = stack;
threadContext.uc_stack.ss_size = sizeof(stack);
makecontext(&threadContext, (void*)start, 0);
Run Code Online (Sandbox Code Playgroud)
不相关,但请确保您还在示例代码中释放了malloc内存.
| 归档时间: |
|
| 查看次数: |
905 次 |
| 最近记录: |